Monday, June 17, 2013

Fix for View Criteria Search Results with DB Pooling Enabled

In order to minimize DB connections usage and optimize ADF runtime performance, I often prefer to enable DB pooling and keep data between requests in memory (jbo.doconnectionpooling = true and jbo.txn.disconnect_level = 1). Read more in this post - Stress Testing Oracle ADF BC Applications - Do Connection Pooling and TXN Disconnect Level. There is one bug related to the View Criteria search results - rows are not always displayed correctly. I will describe the fix.

Sample application - SearchRefreshDBPoolApp.zip is enabled with DB pooling:


Disconnect level is set to 1 to keep data between requests in memory:


Do a search for the last employee in the rowset - Gietz:


As soon as results list will be filtered:


Clear up search criteria for the LastName and search again with blank criteria to get all rows:


Not all rows are retrieved to the UI, you can try to scroll up and down - still results list is incomplete. Only if you press Search button second time - then results list will be refreshed and bring correct results.

The fix is to set ContentDelivery=Immediate for the table component:


After repeating same test scenario, results list will be complete from the first time:

Saturday, June 15, 2013

Passing Payload Value from ADF to BPM Process Task

This post describes how to pass payload value from ADF programmatically and assign it to the BPM process task. This is one of the important points for ADF/BPM integration, along with programmatic process task initialization we are able to assign process task payload and pass dynamic values.

Sample process from demo BPM app -  adfbpmapp_ps6_v2.zip, works with Employee type payload. Employee data is submitted in the input and output of the process task:


Process is initialized programmatically, AssignEmployee task is process automatically by completing this step from ADF through BPM API. User is navigated to AssignEmployeeReview task automatically - this is how sample process works:


Once new process task is initialized, we are setting payload variable based on initialized task ID and processing the task. From the same bean, tasks table is refreshed by the ADF poll component to display latest changes. BPM process task starts asynchronously and ADF UI may not display it immediately:


Payload value is assigned by getting task payload XML element and setting value by ID. In this example only Employee ID variable is initialized for the payload:


BPM process works in the similar way as ADF Task Flow - navigation between process tasks is controlled by outcomes. As you can see SUBMIT outcome is defined in the task definition:


Finally ADF UI part defines ADF Poll component to reload tasks table automatically every 10 seconds to display asynchronously started BPM task list:


User redsam1 selects employee row - 101 in this test:


Goes to Assigned Tasks tab and from there starts new process (payload for Employee ID is retrieved from current row set in Employee Data tab):


As you can see from the screenshot above - task was created, but not yet displayed in the list. Since list is auto refreshed - it will be loaded in the next 10 seconds:


If you go to the standard workspace task flow and display associated human task UI for selected process task, it will display Employee ID 101 from process payload assigned by method in ADF:


Submit selected task for further processing, payload value will be transfered by BPM to the approver redsam2 user:


Through BPM process instance tracker we can double check - payload was set programmatically correctly, value 101 is displayed:

Tuesday, June 11, 2013

Oracle Forms to ADF Modernization Reference - Convero (AMEC) Project

I'm excited to announce our new Oracle Forms to ADF modernization reference published on Oracle OTN site - Convero (AMEC) project:


You can read all the details and description from the reference document. I just can add from myself that Convero (AMEC) project is innovative in terms of technical approach to modernize such large scope Oracle Forms system to ADF.

Thursday, June 6, 2013

Cache Results for ADF Iterator Property

There are various properties in ADF developers tend to click around. Based on my experience from various ADF projects and what strikes me the most - often some property change is done without actually understanding what it means for application performance, at first comes desire to find solution with any cost. I will give you one example related to CacheResults property for ADF bindings iterator.

By default CacheResults property is set to True:


This means when requests are submitted from ADF UI, current rowset is not re-executed again if rows were fetched already. For example when table is loaded and users selects different rows, during new row selection there is no SQL query executed again:


On opposite, when CacheResults is set to False:


Before every request ADF will re-execute SQL query and fetch previously already fetched rows again and again. Obviously this is not what you want in most of the cases, so be careful with CacheResults property. SQL is executed and rowset is fetched:


In this example - CacheResultsApp.zip, such behavior happens on every row select. I just wanted to show what effect you can get by setting CacheResults property to False.


For my specific case, developer wanted to make sure data is refreshed everytime when there is change in DB. But later this requirement was dropped, however no one remembered to set CacheResults back to default, form complexity was increasing until performance became bad. Ok, but now it is fixed !

Wednesday, June 5, 2013

BPM 11g - Starting New Task from ADF with BPM API

One more step in ADF/BPM integration I would like to cover today. This is based on BPM 11g PS6 ADF sample application with included BPM workspace ADF task flow - Customized BPM 11g PS6 Workspace Application. I will show in this post how you can start new process instance from ADF with BPM API.

Sample application - adfbpmapp_ps6_v1.zip implements custom ADF Task Flow with ADF UI Fragment, where regular ADF UI table component is implemented to display current user tasks. Additionally there is a button "Start New Task" to start new process and assign further tasks:


Once "Start New Task" button is pressed, it calls action listener from the backing bean, where BPM functionality is invoked. If task was started successfully and task ID was generated, we are going to report it to the user:


Task is started by getting tasks possible to initialize from BPM context connection for current active user. Process instance is created for such task and task ID is retrieved. In this example I'm getting first available initiable task. BPM API returns initiable task even if user is not granted permission to start it through BPM role, is enough for the user to be part of the process. For this reason there is additional check if user has appropriate BPM swim lane role:


In this example must be granted GroupManagers swim lane role to be able to start new task and call task initializer activity:


User redsam1 is able to start new task through BPM API, information about just started task ID is displayed along with task info in the table:


The same task info is displayed in BPM workspace task flow, where task form can be accessed:


User redsam2 is not granted with GroupManagers swim lane role, and this user can't start new tasks as reported:

Friday, May 31, 2013

New ADF Academy - Impressive Concept for ADF eLearning

There is new free ADF eLearning material available from Oracle - ADF Academy delivered online and available to anyone. You can access and learn from the first published course - Developing Applications with ADF Mobile.

One of the great things about this material - different technical resources are collected into one single place. Plus interactive way of viewing these video/audio resources makes ADF learning real fun !


Thursday, May 30, 2013

ADF Fragment Data Reload with Poll Component

If you are looking for simple but effective solution to refresh data in ADF, you might be interested to check ADF Poll component. This component integrates well with ADF fragments - reload event is isolated in the scope of fragment and not distributed to entire page, means whole page will not be refreshed, but only fragment. I will demo this below with example.

Sample application with ADF Poll component configured to refresh Employees table only - ADFPollFragmentApp.zip.

Employees fragment implements ADF table and Poll components:


Poll is set to initiate reload event every 5 seconds by default. It will stop sending reload events after 600000 seconds. PollListener is defined to implement reload logic:


PollListener re-executes VO SQL for the table and at the end sends Partial Trigger event to perform visual refresh for the Panel Collection UI component containing table with Employees data:


VO is re-executed by accessing iterator bindings from Page Definition:


Main page includes ADF region where Poll component is configured and additionally it contains another table component. There is one more table included to prove that data reload event is not distributed outside of the fragment:


We can see how it works. Open Departments tab from the main page, where no Poll component is configured and select any row from the table - remember your selection, we are going to check it later:


Go to the Employees tab and there check current salary value for Lex De Haan employee. Salary value is 17007:


Open database table and change salary value for the same employee to be 1500, commit your changes:


Switch back to page and you will see that during next data reload Poll event - change will be fetched to the UI:


Similar if you create new record and commit it in the database:


This record will appear in the UI automatically for you:


If you go to Departments, previously selected row still remains correct - this means Poll component was distributing reload event only in the scope of the fragment: