Tracking SQL Queries in ADF Applications
Introduction
Slow and poorly optimized SELECT
queries are a common problem when developing ADF applications. To track SQL performance and other related issues, it’s essential to be able to monitor the queries sent to the database.
Solution
View Object performance issues are primarily connected with the execution of the executeQueryForCollection
method, which populates the View Object with rows from the database.
To track all View Object queries that return collections, you need to override the executeQueryForCollection
method in your View Object implementation. The best practice is to have a single global ViewObjectImpl
at the top of your View Object hierarchy, which all other View Objects will extend.
To log these queries, you’ll add the following code to your View Object implementation class:
public void executeQueryForCollection(Object rowset, Object[] params, int noUserParams) {
System.out.println("VO name: " + this.getFullName());
System.out.println("Query is: " + this.getQuery());
super.executeQueryForCollection(rowset, params, noUserParams);
}
You can use any debugging tool you prefer (e.g., Log4j); System.out
is used here for convenience.
If you test this method, you’ll notice that ADF only logs parameter names (like :vc_temp1
, :vc_temp2
, or similar placeholders), but the actual parameter values are missing.
To view these values, we need to inspect the second parameter of the executeQueryForCollection
method. This parameter, populated by the framework, contains pairs of (name, value) for the parameters. It might seem a bit unusual to use an array of objects of arrays of objects (Object[][]
) for saving parameters, but there must be a reason. We can extract these values using the following helper method:
private void getParametersValues(Object[] params) {
if (getBindingStyle() == SQLBuilder.BINDING_STYLE_ORACLE_NAME) {
if (params != null) {
for (Object param : params) {
Object[] value = (Object[])param;
System.out.println("Name=" + value[0] + "; Value=" + value[1]);
}
}
}
}
You just need to integrate this helper method into your executeQueryForCollection
override, and you’ll have full query monitoring directly from your JDeveloper console:
public void executeQueryForCollection(Object rowset, Object[] params, int noUserParams) {
System.out.println("VO name: " + this.getFullName());
System.out.println("Query is: " + this.getQuery());
getParametersValues(params);
super.executeQueryForCollection(rowset, params, noUserParams);
}
Enjoy Reading This Article?
Here are some more articles you might like to read next: