Preventing unwanted query executions in ADF BC when used in Non-UI applications

Oracle ADF enables you to build rich enterprise applications very rapidly. The UI aware model and tooling support doubles your productivity and removes a lot of boilerplate code from your application. However, when you plan to reuse ADF Business Components built for a UI centric application( e.g a web application), in non UI application (e.g a console or a batch application) you can play smartly which may avoid some unwanted query executions. This post is meant for addressing few such scenarios with some simple tricks.

When you use ADF BC in Non-UI app, a couple of points that you need to be aware of are :
  • If you have an LOV(choice list) enabled attribute in a view object, then framework will kick off query for reading list of values whenever you set value for this attribute( if the list is not yet populated). This is desirable when use in a web application. It also make sense if the LOV returns multiple values so that all LOV derived attributes will get populated when you set new value for LOV. However if you feel this feature is not required when you use VO in a batch mode, then the rest of this post is for you
  • The above story is applicable for view link consistency property enabled for the view object as well. Sometimes you may not really want this behaviour when use VO in a batch mode program.
The sample attached in the post contains a couple of  framework extension classes fmwk.extension.ModeEnabledViewObjectImpl and fmwk.extension.ModeEnabledViewRowImpl which may help you to prevent the unwanted execution of business components that we discussed a while ago. The The class ModeEnabledViewRowImpl  is extended from ViewRowImpl and overrides getListBindingCount() to return 0 if the view object is used in Non-UI mode. This method will be engaged when framework is about to start executing an LOV query(list binding), and further execution of  LOV query depends on the return value from this method. The class ModeEnabledViewObjectImpl is extended from ViewObjectImpl and it has a custom method to switch between UI and Non-UI mode for use by the client. To engage our custom classes at runtime, the view object that you plan to use in batch mode should be configured to use these classes as view object and view row class respectively. An example is here:

 <ViewObject  
  xmlns="http://xmlns.oracle.com/bc4j"  
  Name="DepartmentsVO"  
  Version="11.1.2.62.94"  
  ... ...
  CustomQuery="false"  
  PageIterMode="Full"  
  UseGlueCode="false"  
  ComponentClass="fmwk.extension.ModeEnabledViewObjectImpl"  
  RowClass="fmwk.extension.ModeEnabledViewRowImpl">  

Usage of this custom VO implementation when used in batch mode is here:

 public void doBatch() {  
      ModeEnabledViewObjectImpl modeEnabledDeptVO =   
        (ModeEnabledViewObjectImpl)getDepartments();  
      try {  
           //Set the flag to true to prevent unwanted query
           modeEnabledDeptVO.setNonUIMode(true);  
           Row deptRow = getDepartments().createRow();  
           deptRow.setAttribute("DepartmentId", -11);  
           deptRow.setAttribute("DepartmentName", "Foo");  
        //LocationId is an LOV enabled attribute.  
        //this usually triggers an LOV query when you set value  
        //This example prevents this LOV query   
           deptRow.setAttribute("LocationId", 1700);  
           modeEnabledDeptVO.insertRow(deptRow);  
           this.getDBTransaction().commit();  
      } finally {  
           //Reset the mode after the use in batch oeration
           modeEnabledDeptVO.setNonUIMode(false);  
 
      }  
 }  

Download 

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R2 11.1.2.3.0 + Oracle XE]

How to run this sample?

This sample uses classic Department and Employees example. The LocationId attribute in DepartmentsVO and DepartmentId attribute in EmployeesVO are LOV enabled attributes. Our aim here is to prevent LOV queries when you set value for these LOV enabled  attributes. Steps to try out this sample are listed below:

1. Set Java option as -Djbo.debugoutput=console in Run/Debug/Profile for the model project. This is just to trace the queries being executed at runtime.
2. Execute  test() method in AppModuleAMImpl  using AM tester ( or  by running test.jsf). Check the console window. You may not see any SQL trace.
3. Now try flipping(set as false) value for setNonUIMode(..) listed at the beginning of the test() method as shown below and then execute test method once again.

            modeEnabledDeptVO.setNonUIMode(false);
            modeEnabledEmpInDeptVO.setNonUIMode(false);

You may notice extra queries being executed for LOV while creating rows. So last time in Step 2, our custom components prevent these query executions. Similarly you can test view link consistency as well.

Comments