Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 18 hours 7 min ago

ADF BC 12c New Feature - Entity-Level Triggers

Tue, 2014-07-08 08:13
We have triggers support in ADF 12c! Powerful new feature is available - Entity-Level triggers. Previously it was often confusing if certain use case belongs to validation rule, or it is more generic business logic. Everything was implemented as part of validation rule in the EO. ADF 12c provides cleaner approach by supporting option of Entity-Level triggers, along with regular validation rules. Validation logic can be implemented as part of validation rule, non-validation (but still dependent on data management lifecycle) logic can be implemented as part of new Entity-Level trigger.

ADF 12c EO wizard offers new section - Entity-Level Triggers. Here you can define different triggers, for example - before update, before commit, after insert, before delete, etc.:


This means, you can inject any custom code to be invoked by the framework, during certain event from ADF BC lifecycle.

Wizard allows to select trigger type and define Groovy expression, here you can call any custom method from EO Impl class. However, there is one trick related to expression execution in untrusted mode - I will describe it below (thanks for a hint to Steve Muench):


Custom method is defined in EO Impl class, you can see it here:


If you simply define a trigger and try to test it, you will get an error about not permitted method call:


Trigger expression by default is running in untrusted mode, this means your custom method must be annotated with @AllowUntrustedScriptAccess. If you don't want to annotate, you could change trust mode to trusted for the expression. By default trust mode is set to be untrusted:


Change it to trusted mode:


Trigger should work just fine now. Try to change data and save:


There are two triggers defined - before update and before commit. Both of these triggers are invoked successfully, as you can see from the printed log (right before update and before commit):


Download sample application - ADF12cApp.zip.

ADF 12c (12.1.3.0.0) - View Object Declarative Mode is Default

Sat, 2014-06-28 10:25
Important event for ADF community - new release of ADF 12c (12.1.3.0.0). Quite many new features overall in the framework and there are some related to ADF BC. I will focus on ADF BC and highlight one new feature, which I think is very important to know. This is related to ADF BC VO mode, from now on - Declarative VO mode is a default. There is no longer Expert mode, this is renamed to Custom SQL and overall wizard for VO Query is changed. Read more about it in developer guide - 5.3 Working with View Objects in Declarative SQL Mode.

Every time when creating VO based on EO, JDeveloper will generate VO with Declarative mode:


This is how VO Query wizard looks like now. VO Query is declarative and will be generated on runtime. Although, it doesn't mean all attributes will be checked dynamically by default. On opposite, all attributes by default will be included into generated query:


Option 'Calculate Optimized Query at Runtime' is selected by default, this means Declarative mode is on. List of attributes is displayed, these attributes will be always included into SQL query. If we want to exclude some of them, we need to set Selected in Query = false for the attribute:


In sample application, I'm going to set this property to be false for all attributes, except a key:


If we return back to the VO Query wizard screen, now only key attribute remains selected:


UI is developed to display six attributes:


Only displayed attributes are included into SQL statement:


Download sample application - ADFBC12cApp.zip.

Time Selector for ADF Graph and Data Filtering

Fri, 2014-06-27 12:38
ADF graph with date/time data in X axis, could be configured with time selection and scrolling functionality. This could be very useful for such use cases, where we want to analyse specific set of data in the selected period of time. User could select a time range in the graph and display data from the selected range. We are going to include similar functionality into new release of our Red Samurai ADF Performance Audit Tool.

Here you can see example implemented in the sample application - ADFGraphApp.zip. User can select a time range to analyse data peaks, data will be filtered and displayed in the table below:


This is out of the box ADF graph feature - time selector. User is allowed to adjust selection range as he wants - move right or left. Data in the table below stays in synch with time range selection changes:


Another out of the box feature - graph zooming/scrolling along X axis with date/time data. This is quite useful, especially when data for long time periods is displayed and user wants to see changes in the specific period in more detail:


Zooming/scrolling is enabled with scrolling="on" property for 01Axis. Time selector is configured with separate element - timeSelector. You must set start/end interval and define time selection listener, so it could update dependent data displayed in the table (as in this example):


Important thing to remember, when working with date/time data displayed in X axis. You must ensure, duplicate data (using same date/time) is aggregated - otherwise, graph will be displayed incorrectly. You can set data aggregation directly in the graph binding with aggregation type setting:


The last bit - time selection listener. Here you can read start/end date/time intervals and apply these intervals to filter any dependent data. I'm using different VO instance with declarative View Criteria, to filter based on start/end for Hire Date. Setting bind variable values and re-executing VO instance:


More info you can find in ADF developer guide - 24.8 Adding Specialized Features to Graphs. Time selection listener code in given sample application, is based on example from ADF developer guide:

ADF BC Reserved Mode for DB Connection Critical Applications

Fri, 2014-06-20 06:31
With this post I would like to explain how you can control ADF BC mode and switch from default managed to reserved mode and back. With default managed mode, there is no guarantee in ADF BC for DB connection to stay assigned for the user session. Why it is highly recommended to design your ADF application in such way to be compatible with default managed mode, there are exceptional scenarios when we want to guarantee DB connection to stay the same between requests. Reserved mode allows to guarantee DB connection and there is a way to switch between modes on runtime. You can read more in ADF developer guide - 40.4 Setting the Application Module Release Level at Runtime.

Sample application - ReservedModeADFApp.zip, is developed to demonstrate how you can switch between managed and reserved modes. You can change any field and click Prepare Data, this will post it to DB. By default, data will be lost during the next request. However, if you click Enable Reserved Mode - ADF BC will switch to reserved mode and DB connection will stay assigned, until you will switch back to managed mode again:


Prepare Data button calls ADF BC post operation, to post data to DB. There are two key methods here - enableReservedMode and disableReservedMode. As you can see, it is pretty straightforward to switch between modes, you only need to call setReleaseLevel method available as part of ADF BC API:


Application Module configuration is set with all default settings, also DB pooling is enabled:


We should test how it works to switch between two different modes - managed and reserved. Let's change data in any field, for example Hire Date:


Click Prepare Data button to post changes for Hire Date to DB:


Click Save button to commit transaction:


At last, click Cancel button to check if previously posted changes were committed to DB:


You can see - changes in Hire Date are reverted back, as change was not saved after it was posted. Application Module is set with DB pooling, means during each request it will return DB connection back to the pool and get another one on the next request. This would mean all changes posted to DB are lost:


This is correct behaviour. But in some exception cases, we would like to keep DB connection between requests. We could force this by switching Application Module into reserved mode. By default, when DB pooling is enabled, you can see there are zero DB connections used (connections are returned quickly to the pool after request completion):


We should repeat our test, but little different now. Before posting changes to DB, click Enable Reserved Mode button - this will switch Application Module to reserved mode and guarantee DB connection across requests:


You can see from the DB connection monitoring, one connection gets reserved now and stays assigned:


Click button Prepare Data now, to post changes to DB when reserved mode is on:


Click Save button to commit transaction:


Click Cancel button to see if recent changes will be reverted:


Changes are not lost this time, means posted data was successfully committed in the next request, when Save button was pressed:


Changes were posted and committed to DB, we can switch back to default managed mode. Click Disable Reserved Mode button:


You should see from DB connection monitoring graph, previously reserved DB connection should be returned back to the pool:

Better Control for ADF UI Shell Tab Closing Order

Tue, 2014-06-10 14:02
This is third post in the series about ADF UI Shell usability improvement, you can read previous one - ADF UI Shell Usability Improvement - Tab Contextual Menu. When you work with Web browser tabs, expected behaviour after closing the tab in the last position is the next tab available on the left side to be opened. However, this works differently in ADF UI Shell and could be improved. I will describe how.

Here you can see three tabs loaded in ADF UI Shell, this comes with sample application - MultiTaskFlowApp_v5.zip:


If I would close tab in the last position - Locations, by default the first tab Departments would be set as current. However, users would expect Employees tab (next to the closed Locations tab) to be set as a current. This is how it works by default, when closing the tab in the last position - first tab becomes current:


In order to fix this behaviour, you need to update ADF UI Shell method responsible for tab removal and next current tab selection. By default, if closed tab is in the last position (there are no tabs further right) and counter is reaching maximum tabs, counter is reset to 0. Obviously there will be tabs available from position 0 and further to the right, however this would set as current tab not the closest one to the closed tab - but just first from the start. Highlighted code is the one that was added by me - when counter is reaching the end, instead of switching to the first position 0, I'm iterating leftwards. Once first tab on the left will be located, this tab will be set as current:


Again, I load three tabs and try to close the one in the last position - Locations:


This time proper tab gets selected - the next one on the left to the Locations, Employees tab:

ADF UI Shell Usability Improvement - Tab Contextual Menu

Sat, 2014-06-07 08:34
In my previous post - Improving ADF UI Shell - Tab Closing Icon Adjustment, I was describing how to implement ADF UI Shell tab closing icon to be located directly on the tab itself. Today I would like to share one more usability improvement - tab contextual menu. You could implement such functionality as - 'Close', 'Close All' and 'Close Others' with contextual menu invoked from the tab.

Sample application with ADF UI Shell tab contextual menu - MultiTaskFlowApp_v4.zip. Here you can see how ADF UI Shell tab contextual menu looks:


User can select a tab and choose to 'Close Others':


All tabs, except current will be closed - quite useful:


Contextual menu is implemented for ADF UI Shell tab with Client Listener calling custom Java Script function and Client Attribute to pass current tab ID:


Custom Java Script function is calling ADF popup, displayed as menu list. This popup is implemented with ADF command menu items - representing each option from contextual menu. Action Listener for menu item is configured with JSF attribute to pass current tab ID:


Here you can see methods responsible to close current tab, all tabs and other tabs. When closing all tabs or other tabs, it is important to check and close only those currently active:


You may face a conflict between tab contextual menu and regular browser menu for contextual action (typically right click). To block browser menu for contextual action, you could use code given above: