Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 3 hours 40 min ago

Improving Scrolling Performance in ADF Read-Only Tables with Row Selection Timeout

Sat, 2014-01-18 08:22
There is great new feature available in ADF 11g PS6 and ADF 12c - option to enable row selection timeout for ADF read-only tables. By default, when user is pressing up/down keyboard keys - every time row gets selected, even if user is navigating through multiple records, before selecting the one he needs. With row selection timeout enabled, table rows will not be selected while scrolling, until scrolling stops and required record gets selected. This should be default setting, I wonder why Oracle didn't enabled it by default.

I will describe first, how scrolling in ADF read-only tables works by default. For the test purpose, ADF BC method setCurrentRow is overridden to track how many records get selected while navigating with up/down keyboard button:


In order to see output message - make sure to enable ADF logger for Employees VO implementation class:


Select one of the available rows:


You will see row selection action is executed and reported in the log:


Navigate few records down:


You will see in the log, all records were selected - while navigating from the first to the last records:


We can tune this behaviour by enabling row selection timeout, while scrolling with keyboard up/down keys, timeout value will not be exceeded and row will not be selected until user will stop. Select ADF table component:


Change property - SelectionEventDelay, by default it is disabled. This property is available in ADF 11g PS6 or ADF 12c:


Set property SelectionEventDelay to be enabled. Selection timeout is 300 ms, meaning row is selected, if delay between pressing up/down keyboard keys is more than 300 ms:


With SelectionEventDelay = enabled, repeat the same test as above. Select a row in ADF read-only table:


Check in the log - row selection action was invoked:


Navigate few records down and stop:


There will be no records selected in between, only the last one - this will improve ADF read-only table scrolling performance with keyboard up/down keys greatly:


Download sample application - ADFTableScrollingTimeoutApp.zip.

Accessing Custom Attribute Property from ADF UI Expression

Wed, 2014-01-15 12:27
You may not know, but it is possible to access custom property defined for the VO/EO attribute from ADF UI expression. This may turn useful, when implementing custom generic functionality and standard attributes are not enough. In this example, I'm using custom property - alternativeName, in real use case this will be something else. Here I will pass alternative name for the attribute through this property:


Custom property defined for the attribute, can be accessed from ADF UI Expression, by referencing properties map - bindings.AttributeName.attributeDef.properties.PropertyName:


This is how property is accessed, later it can be displayed on UI - see label text for the CommissionPct attribute:


You can download sample application here - CustomPropertyApp.zip.

ADF BC Application Module Instance Timeout and Web Session Timeout Dependency

Sat, 2014-01-11 02:23
What happens with AM instance, when Web session times out? I would like to answer this question. To find an answer, I have developed sample application with special settings for AM configuration - AMInstanceTimeoutApp.zip. This is important to understand, because we should try to avoid frequent AM passivations, same as frequent AM activations. Passivations consumes server resources and delays request processing for current active users.

We already know - when AM idle instance timeout is set to be less than Web session timeout, during user inactivity there will be AM passivations and activations happening. To minimize number of passivations/activations, we need to increase Referenced Pool Size, along with increasing AM idle instance timeout (read here - How to Minimize Number of ADF BC Application Module Activations).

Customized AM settings for the sample application:

1. Referenced Pool Size = 1, to simulate high load and to see what happens when second user arrives

2. Minimum Available Size = 0, to make sure all AM instances will be removed after timeout

3. Idle Instance Timeout = 900 (sec.), instance will be marked as candidate for removal after 15 mins.

4. Pool Pooling Interval = 60 (sec.), inactive AM instances will be removed in 1 minute intervals


Web session timeout on contrary to AM instance timeout is set to be less - only 5 minutes. This is done on purpose to timeout Web session, before associated AM instance will be timed out:


As practical test shows - once Web session times out, if another user accessing application before pool pooling interval - passivation will happen. This means, AM instance was not yet removed and is still reserved - as there are no available AM instances (Referenced Pool Size = 1), passivation happens and instance is given to the new user.

Web session times out for the first user:


Second user is accessing application, passivation happens for the AM instance previously used by already timed out session:


However, if second user would wait a bit more after first user session timed out - precisely would wait until pool pooling interval, there would be no passivation. This means, when Web session times out - AM instance is not removed instantly, it will stay active until the next even of pool cleanup (pool pooling interval). In my sample I set this interval to 1 minute, in real application it could be 5-10 minutes.

Web session timeout happened and after pool pooling interval - AM instance was removed:


If second user is accessing application at that time, there will be no passivation reported:

Simple Example for ADF Active Data Service

Tue, 2014-01-07 13:24
Active Data Service in ADF is very useful functionality, it allows to push data to the UI, without extra refresh/reload. However, due to its complexity, is not used too often. My goal is to provide as much as possible simple example for ADS use case in this post. In the future posts, I plan to post updated samples with more complex use case implementations.

ADS is configured in adf-config.xml file, here you can download complete sample application - LongRunningTaskPushApp.zip. There is active output text component, it displays number of open jobs and is refreshed by ADS:


Once we navigate to the Employees tab - Open jobs counter is reloaded:


Separate thread, where we generate new jobs is started when ADS is activated and is stopped automatically, when ADS is deactivated (when navigating away from page or closing browser):


Thread is stopped automatically, when browser is closed or navigating away to other page:


Active output text value is retrieved from managed bean method:


This managed bean is registered in session scope and is responsible to manage ADS lifecycle:


We can see that managed bean method is accessing binding and gets initial value from there - it comes from ADF BC attribute:


This relationship is defined in Page Definition - initial value is retrieved from ADF BC:


There is post construct method - we are setting up ADS model info, basically registering active output text component value to be reloaded automatically by push from ADS:


There are two standard methods from ADS model overridden to control ADS lifecycle start and stop events:


As you can see above - thread to push ADS changes is created in start method, automatically when ADS gets initialised after post construct method. Thread is stopped automatically, when ADS is deactivated (this happens when browser is closed or navigated to other page).

Active output text is reloaded by triggered method, where ADS event is generated - using registered active output text value:


When opening Employees tab, Open jobs counter is reloaded from resetData method, referenced from panel collection visible property:

ADF Dynamic ADF BC - Loading Multiple Instances (Nr. 100 in 2013)

Mon, 2013-12-30 03:25
This is Nr. 100 post in 2013 !

We learned how to build dynamic ADF BC passivation/activation safe in the previous post - ADF Dynamic ADF BC - Surviving Passivation/Activation Events. There is one more trick to learn - how to reload and open UI with dynamic ADF multiple times. This is useful when dynamic ADF form can  be opened from multiple menu items, passing parameter and re-drawing dynamic ADF UI.

This is implemented in the sample - ADFDynamicReportUI_v5.zip. Custom method from Application Module class constructs View Definition, each time when form is loaded from the menu - this method is invoked with parameter and new View Definition is created:


For the test purposes, we set Hire Date to be displayed only when parameter is not NULL:


Before creating new View Object instance, we should check if our dynamic View Object instance already exists. If yes - we should remove it first and only then create new one (otherwise there will be error about existing View Object instance with the same name):


This is mainly all about loading multiple instances. Now I will describe several improvements in UI part. ADF 12c supports declarative component tag, this simplifies complex ADF UI rendering. Sample application ADF UI form renders different kind UI components from iterator using ADF UI dynamic component tag:


We are referencing attributeModel from iterator and accessing Page Definition bindings:


Dynamic form in ADF 12c is created simply by drag and drop and selecting dynamic option - fairly simple and stable.

Sample application is based on Multi Task Flow Binding, described in my previous post for ADF 12c - Smooth Migration from ADF 11g R1/R2 Apps to ADF 12c. I'm loading ADF Task Flow with dynamic ADF UI, passing additional parameter for the second menu option (Hire Date will be displayed):


ADF Task Flow with dynamic ADF UI is closed and loaded from the menu dynamically, controlled by Multi Task Flow binding:


You can try to open first or second menu option, this will load the same ADF Task Flow, but reinitialise dynamic ADF BC with different parameter - dynamic ADF UI will be displayed accordingly:

ADF Dynamic ADF BC - Surviving Passivation/Activation Events

Fri, 2013-12-27 02:07
ADF dynamic ADF BC and dynamic ADF UI implementation is useful functionality and is required almost in every larger project. Primary area where this functionality is applied - report parameters screens, instead of building hundreds of static report parameter screens for every report, we can build one dynamic and regenerate required ADF BC objects structure, together with dynamic ADF UI. Here you can read my previous post for the same topic - ADF Generator for Dynamic ADF BC and ADF UI - Recreate. Today post provides improved sample application with added support for ADF dynamic functionality working in passivation/activation event scenario.

Download updated sample application - ADFDynamicReportUI_v4.zip. Previous sample application contained one dummy VO - DynamicView:


This VO was replaced on runtime with real dynamic VO, created programmatically in HrModule class. This didn't worked in stress test environment, simulated by disabling AM pooling:


Null pointer exception for ADF dynamic form - activation event was failing:


It was failing, because on activation, ADF runtime was trying to activate original dummy VO - not the one we have substituted programmatically:


In theory it should work to remove dummy VO and change it with programmatic one, but really it fails on activation event:


Solution is pretty simple for this - we can get rid of dummy VO completely and rely directly on VO instance created programmatically on runtime. There is no need to define dummy VO in AM Data Model:


There is no need to have dummy VO either:


As there is no dummy VO anymore, no need to remove it's instance. We can simply create new programmatic VO instance with given name:


In page definition we should reference VO instance by the same name, obviously it will be highlighted as design time error - as there is no such VO instance defined statically, but this will work on runtime:


There are few additional improvements to survive passivation/activation events better - I will list them all below:

1. Non editable primary key - you should add primary key attribute and hide it to be non editable


2. If there is no default value for the attribute, it can be marked as not selected in query and there will be no need to include it into SQL statement


3. Not specifically related to passivation/activation - but for dependent LOV's, we need to set AutoSubmit=true for the parent attribute:


Dependent attribute should be set with backward dependency, this will reset attribute value automatically, when parent attribute value is changed:


4. SQL statement includes only selected attributes, where default value is set:


5. Dynamic VO doesn't passivate and activate correctly by default. We need to passivate and activate such VO manually. Standard method for passivation should be overridden, we can read current row attribute values and passivate them:


Standard method for activation should be overridden, to activate and set values to the current row attributes back:


6. If there are LOV's created dynamically, all such LOV's must be assigned with primary key:


Here you can see how it works on UI. Let's select Location Id, based on selected value LOV for Department Id is filtered and returns 50:


If you change Location Id, Department Id will be cleared automatically and user could select new Department Id value corresponding to the currently selected Location Id: