Advanced PL/SQL integration with ADF (new API)

JDev: Source: GitHub
Till ADF 11g, we have been integrating ADF with PL-SQL modules having user-defined types with "oracle.sql" packages. We have used oracle.sql.StructDescriptor and oracle.sql.ArrayDescriptor to create implementations of user-defined types on Oracle database.
Since the migration to 12c, we have been getting a warning that most of oracle.sql's APIs have been deprecated.

The new solution is to use java.sql.Struct (not STRUCT) and java.sql.Array (not ARRAY).
However, using the Array API has been made a bit tricky. Now we do not have the support of ArrayDescriptor to create a definition object for the user-defined type. Let us see how exactly we go about it.
This is the use case we will solve: 1) Call a packaged procedure with a user-defined type as IN parameter. 2) Modify the object and return as an OUT parameter of a user-defined type. 3) Intercept the out parameter in ADF and read the modified contents.
We will be using the default HR schema. …

Pass custom objects across ADF taskflows (by value or reference)

JDev: Source: GitHub
We usually pass along parameters of native data types across ADF task-flow calls. We set up input and output parameters for the source and target task-flows, and we access the variables from the pageFlowScope map.
Absolutely nothing wrong with this approach.
But how about a scenario where we process and populate a POJO variable from the source task-flow, and expect a POJO variable on the target task-flow to be populated via a declarative route?
The Parameters section of a bounded task-flow allows you to set a specific property on its managed bean to which the object being passed across will be assigned.
While passing along an object across task-flows, ADF lets you choose whether you want to pass the object by value or by reference. Let us examine the difference between the two approaches.

This is what we want to achieve: Initialize an Employee variable (employeeInTarget) in the source task-flow and pass this variable as input to a target task-flow. Thi…

Manual passivation and activation of Application Module instance variables

JDev version:
We are aware of ADF's passivation and activation mechanism. We know that when we need to persist the state of a transient attribute of a view object, we ask the framework explicitly to passivate such an attribute.
However, sometimes we may also need to persist the state of an Application Module class' member variable. Let us say that we have an Integer variable which gets incremented on a certain operation. At a high user load, or when doFailover is turned on, the application module instance is passivated and activated almost on every request.
The ADF framework passivates only that data which is required to initialize the application module to the earlier state, and the ones that we explicitly ask for (by checking the passivate checkbox). All other instance level values are rejected and re-initialized. Let's see an example.
To demonstrate this, I have turned off application module pooling, to ensure all requests are forced to be passivated to the d…

Advanced programmatic view object in 12.2.1.x

JDev version: Source: GitHub
The previous versions of ADF required a lot of knowledge of framework methods, while attempting to create programmatic view objects based on non-SQL data sources, such as a PL/SQL ref cursor.
This blog shows you how to create a search form, which passes a department id to a packaged procedure, and display results based on a ref cursor returned by the procedure.
Create a simple procedure, which returns some employee data, based on a department_id entered by user.

Create a view object - EmployeesVO, and select Programmatic while selecting Data Source. Create the necessary view object implementation class. Create transient attributes for the columns you need to display on the GUI.

If you open the EmployeesVOImpl class, you will see that JDev has extended it from oracle.jbo.server.ProgrammaticViewObjectImpl.

This class contains an overridden getScrollableData method, and this is the only method we need to populate in order to display data from the …

Keyboard shortcuts on ADF table

JDev version: Source: GitHub
We often create applications which require very quick data entry. As a real world example, imagine creating a supply-chain application for an e-commerce vendor. The computers available at warehouses are not equipped with mouse either. A common request from such users is to enable the application with the usual keyboard shortcuts, in order to allow fast data entry.
Now, there is a great deal of discussion as to how much we should be overriding the default browser shortcuts. Some web developers are quite vocal in their view of not overriding basic browser shortcuts such as Ctrl+S, Ctrl+T or Ctrl+W. That discussion is beyond the scope of this blog.
This blog mainly deals with creating custom shortcuts, along with Control or Shift key modifiers.
The setup is simple - an ADF application which displays employee records from the HR schema. The user selects a record and uses keyboard short-cuts to perform operations such as:
a) copying and pasting a r…

Efficient dynamic query in ADF

JDev version: Source Code: GitHub
Use Case: Quite often, we are required to attach dynamic where clause to an ADF view objects's query. Although we do have view criteria to support our cause, more often than not, they do not quite support complex business logic to derive dynamic where clauses.
The GUI:

We usually make use of ViewObject's setWhereClause API to attach a dynamic where clause. However, a common mistake is to write a dynamic query like this:

Now this approach, although technically correct, leads to 2 problems: 1. SQL Injection - imagine someone passing first-name as 'Steven' (with quotes). Your entire SQL statement goes for a toss. 2. Improper query caching - let's explain this with some data and examples.
Imagine you have a very complex query, running on a table with a huge volume of records. The DBAs will usually attach a SQL profile to your query. Now when you have a sql which is a new String for every execution, it effectively creates a ne…

Reset ExecuteWithParams - a different approach

This blog speaks about a quick and efficient way to clear a form based on a View-Criteria, which is exposed on the GUI as an ADF form field.
The setup is simple enough.
1. Create a ViewObject - EmployeesVO, based on the EMPLOYEES table of HR schema. 2. Create a ViewCriteria - EmployeeSearchCriteria, with criteria of your choice. 3. Shuttle the ViewCriteria onto the View Object's Application Module instance. 4. Drag and drop the ExecuteWithParams action on the GUI as an ADF form. 5. Add two buttons - Search and Reset.
Here's how it stands now:

And this is how the GUI looks:

The "Search" button calls the ExecuteWithParams action. Nothing exciting there.
But how do we reset the form? One crude way is to just get hold of each attribute binding, and setting them to NULL. But what if your View-Criteria has many attributes to search on? It becomes really tedious to individually set each attribute to null.
Here is where the ADF BC comes to our rescue.
The ViewCriteria class…