Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 13 hours 37 min ago

ADF BC View Object Change Notification Listener

Wed, 2014-09-10 11:15
ADF BC allows to define triggers to listen for row changes on VO level. We can listen for row updates, inserts and deletes. This can be useful, if you would like to invoke specific audit method or call custom methods to populate dependent transient VO's with updated data.

To enable such triggers, you must add a listener for VO, this can be done during VO creation from standard create method:


ADF BC API methods, such as rowInserted, rowUpdated, rowDeleted can be overridden. These method will be invoked automatically by the framework, when change happens. You can check rowUpdated method, I'm getting changed attribute names (actually it calls this method for each change separately). Getting changed value from current row, also retrieving posted value:


CountryId attribute is set to be refreshed on update/insert, this means change event should be triggered as well, even we would not change this attribute directly:


We should do a test now. Change two attributes - Street Address and State Province, press Save button:


Method rowUpdated is invoked two times, first time for Street Address change (method is invoked before data is posted to DB):


Second time is invoked for State Province change. This means, we can't get all changes in single call, each change is logged separately. It would be much more useful to get all changes in the current row through a single call:


After data is posted, Country ID attribute is updated - this changed is tracked successfully:


Let's try to create new row:


Method rowInserted is invoked, however it doesn't get data yet - key is Null:


Right after rowInserted event, rowUpdated event is called in the same transaction - we can access data from that method. This means rowUpdated generally is more reliable:


Try to remove a record:


Method rowDeleted will be invoked, row data is accessed and key is printed correctly:


Download sample application - ADFBCListenerApp.zip.

Calculating HTML ID for ADF UI Table Row

Sun, 2014-09-07 07:22
Each row in ADF UI table is assigned with ID, this is how rows are referenced in HTML. I had a blog post describing how to set a focus for newly inserted row - Improving ADF UI Table CRUD Functionality with Auto Focus. I'm getting ID for selected row using getClientRowKey method and this method returns row identifier, the one which is used in HTML. Blog reader was trying to use the same method to get ID for any row from the table, but it didn't worked for him. The trick is how to construct a key properly, to use this key to retrieve ID. I'm going to describe it in this quick sample application below.

Sample application UI is straightforward - there is Get Cell Component Name button, when pressed it calls a listener method and prints IDs for each row in CompName column:


Row ID's are retrieved correctly, you can see it from the picture below. With the access to the ID, you could set focus for any row cell you want, not only for the cell from current row as in previous post. Printed row ID's:


You must use getClientRowKey method to retrieve row ID. There must be proper row key supplied, to get correct ID. When you are getting selected row key, there are no issues - but if you want to get ID for any row key, there is one thing to keep in mind. You must wrap row key into a collection (for example, ArrayList). Use this wrapped key to retrieve client row key:


Download sample application - ADFTableFocusApp_v2.zip.

Automatically Applying Get Posted Attribute Method for Row Refresh

Sat, 2014-09-06 10:44
There is out of the box ADF BC method available to refresh current row, see this post for details - Refreshing Single Row Without Full Rollback. There could be use cases, when refresh method is not sufficient (particularly for a row with dependent LOV's) - it may not reset data correctly. Also there is extra SQL query sent to DB, to fetch row data by key. Even it works well most of the time, still it is good to know the alternative. I'm going to present alternative row refresh approach here, using getPostedAttribute method.

User could edit data in the current row:


Press Refresh button:


All attributes are refreshed and synchronised back to the original values, currently available in the database:


UI data is synchronised with the help of Change Event Policy = PPR functionality enabled for iterator in the bindings, we can see synchronisation events executed in the log:


You should know - ADF BC method getPostedAttribute is protected, this is why we need to have a wrapper method in EO Impl, with public access. Wrapper method allows to invoke originally protected method from different class, other than EO Impl:


They key logic resides in refreshCurrentRow custom method, implemented in VO Impl class. This method gets a full list of EO attributes and for all attributes with index higher or equal to 0 (there could be accessors with negative index), it goes and retrieves posted attribute value. Current value is reset back with posted value - this is how attribute value is reset back to the same as it is posted to DB. Sample application is set to use DB pooling, this means it will always return actual value committed to DB, and it will ignore any temporary posted values (each request will get different DB connection):


Row refresh method is exposed to be accessible from the bindings layer:


As it was mentioned above, iterator in the bindings is set to use Change Event Policy = PPR, this is synchronising data displayed on UI with changes in ADF BC automatically:


Keep in mind, no matter if using standard row refresh method or approach described in this post - transaction still will remain dirty, only data will be reset. To clear transaction and revert it back to non dirty, user still must use full Rollback operation.

Download sample application - CustomRowRefreshApp.zip.

Oracle Cloud Friendly - Red Samurai ADF Performance Audit

Mon, 2014-09-01 13:04
I have deployed our tool for ADF performance monitoring to Oracle Java Cloud service. It runs perfectly on the cloud, monitors slow performance and allows to analyse collected performance data. All data is stored in Oracle Database Cloud.

You can access performance monitoring dashboard using this address. Access will be available for a month or so, until my trial account will expire. You would need to use following login credentials - user: redsam, password: We1come@, identity: ltredsamuraictrial99050. You can login and play online with our performance audit dashboard.

There is ADF demo application deployed as well, Summit App - accessible here (same login credentials). This standard demo application is extended with our audit listener to log slow ADF performance into Oracle Database Cloud instance. Use it to generate some audit data, simply by navigating through the application, updating and inserting data.

Red Samurai ADF Performance Audit tool and standard ADF sample application Summit are deployed to Oracle Java Cloud:


This is a main screen of Summit sample application (accessible here), I'm using it to track ADF performance. You could open this application, do several actions and check in performance dashboard to see if any slow actions were reported:


Red Samurai ADF Performance Audit tool, main dashboard displays various performance issues (accessible here) logged. Audited application is fairly basic, this is why I have set performance thresholds to relatively low values - VO execution time to 10 milliseconds, large fetch to 50 rows and slow activation to 300 milliseconds:


You could select issue from the list and check details -Application Module, View Object names. SQL statements with bind variables are available for slow SQL executions. There are very helpful features available, such as historical performance analysis option and application health automatic calculation.

Slow activation tab displays slow activation events, this helps to locate slowest activation Application Modules and possibly to eliminate such slow activations by Application Module parameters tuning:


Drill down displays large fetch and full scan issues for selected Application Module. The most problematic VO instances are displayed first in the graph:


Same graph can be displayed in table view (very helpful for performance troubleshooting) with special sorting method:


You could go and view weekly/monthly history for reported performance issues based on individual VO instance:


Overall system performance screen displays system statistics - queries, transactions, logged users, activations:


System load summary could be helpful, it allows to understand general system load and see the most frequent operations:

End-To-End ADF Cloud Deployment Process

Fri, 2014-08-29 11:37
ADF and ADF BC perfectly runs on Oracle Java Cloud. You could deploy regular ADF application straight away from familiar JDeveloper environment without any hassle. With this blog post I would like to walk through the process of migrating DB model to the cloud and deploying ADF application (enabled with ADF Security) to the cloud.

Here you can download sample application - TreeComponentsCloud.zip. This application is deployed and runs on Oracle Java Cloud, accessible through this link. Online access will be available until my Oracle Java Cloud trial subscription expires (in a month or so). You can login using following credentials - username: redsam, password: We1come@ and identity domain: ltredsamuraictrial99050.

First of all, we should prepare data model - basically you could migrate your local database to the cloud (including data) using JDeveloper wizards. Database Cart wizard could be used for this purpose, simply add all required tables to the cart and set a checkbox to include the data:


You would need to enable SFTP access and note down specific SFTP connection details for Oracle Database Cloud, read more about it in Oracle Java Cloud documentation section Building the Data Model. I have defined Oracle Database Cloud connection in JDeveloper for SFTP access:


Data Model and data upload to the cloud is very seamless process - it does everything just with one click. Entire structure is packaged into archive and sent over to the cloud:


When migration process is completed, we could double check if data is in the cloud. You could expand Oracle Database Cloud connection in JDeveloper and browse through the tables, data should be accessible:


Next we should enable secure access in the cloud. Oracle Java Cloud supports regular ADF Security setup. However, to render Oracle Java Cloud login page, you must include additional security constraint into web.xml (read more about ADF Security in Configuring Security section from Oracle Java Cloud documentation). Here you can see security constraint implemented in sample application web.xml:


You should define regular ADF Security permission for page access. I'm using custom application role - AccountantAppRole:


There is enterprise role AccountantRole defined and mapped with application role from above. This enterprise role is also defined in Oracle Java Cloud service:


Finally there is user defined - redsam, the same user is defined in Oracle Java Cloud service. This user is mapped with AccountantRole enterprise role:


I have defined AccountantRole role under Users group in Oracle Java Cloud service:


This role is mapped with redsam user in the same Oracle Java Cloud service:


Deployment process is identical to the one deploying to local WebLogic server, you could use the same JDeveloper wizard - only select Oracle Cloud as target Application Server from the list:


Once application is deployed, you could login to Oracle Java Cloud service control (looks quite similar to Oracle Enterprise Manager) and check application status, etc.:


Let's do a test now. I will try to login with a user who do not have access to the application. Our sample application is protected by ADF Security, Oracle Java Cloud renders login screen automatically (no need to implement it in your custom application):


Application access will be reported as unauthorised, as expected:


Login with a valid user - redsam (see all login credentials listed in the beginning of this post):


We can access application now. Browse through tree structure and even render a colourful chart:

Session Schedule Information OpenWorld 2014 San Francisco

Tue, 2014-08-26 12:55
I have received my session schedule information for OpenWorld 2014. This year event is going to be quite busy with three sessions. Below you can check session titles along with times, looking forward to meet you in San Francisco !


Session ID: CON2623Session Title: Oracle ADF Development and Deployment to Oracle CloudVenue / Room: Moscone South - 270Date and Time: 10/1/14, 15:30 - 16:15
Session ID: CON3745 (together with Danilo Schmiedel)Session Title: Oracle Mobile Suite and Oracle Adaptive Case Management: A Strong Combination to Empower PeopleVenue / Room: Moscone West - 3018Date and Time: 10/1/14, 16:45 - 17:30
Session ID: CON2495Session Title: Data Caching Strategies for Oracle Mobile Application FrameworkVenue / Room: Marriott Marquis - Nob Hill C/DDate and Time: 10/2/14, 12:00 - 12:45

Transactional Data Caching for ADF Mobile MAF Application

Sun, 2014-08-24 00:20
I have described basic idea for data caching in ADF Mobile MAF application in my previous post - Data Caching Implementation for ADF Mobile MAF Application. Today I would like to extend similar solution to handle transactional data caching. Sample application displays list of tasks, user can update task status and description. These updates will be saved locally, until the next synchronisation time with the server.

Updated sample application with MAF mobile and server side implementations can be downloaded from here - MAFMobileLocalApp_v4.zip. User could select a task on his mobile device:


Update task status and description, these changes are stored locally in SQLite DB, no extra call is done to the Web Service at this time:


Changes for multiple tasks can be synchronised in batch. User could go and change different task without submitting previous changes to the Web Service, update task status:


Finally when user decided to synchronise his changes with the Web Service, he could use refresh option:


When synchronisation happens, we can see activity in the server side log. ADF BC executes update operation for submitted task, update for the first task:


Next is called update for the second task:


MAF task flow is updated for this use case, and is based on the task flow from application described in the previous post. We are not calling Web Service from the task flow method call anymore, this call is done programmatically, during refresh:


Web Service method in ADF BC is updated to check if row exists - if yes, data is updated. If row doesn't exist - no error is thrown, task list will be refreshed and latest changes will be displayed to the user on the mobile device. In the real application, you may inform user about the missing task:


Custom method is exposed as ADF BC Web Service method:


To understand how sample application works on MAF mobile side, we should refer to the task flow diagram. Edited changes are submitted to the local SQLite DB through updateTaskLocal method call. This call invokes Java method, where changes are stored locally in the list of tasks. In addition, record about latest task changes is stored in special table with change history:


We are checking in the change history, if the same task was already updated - if no, we are simply storing task ID. This would allow later during synchronisation to retrieve changed task details and update task first through Web Service, before fetching data. If task was already updated, there is no need to insert task ID again:


During data synchronisation, we are checking if there are any rows changed and stored locally. Only after this check is completed, task list data is refreshed and loaded from Web Service:


Changes for each updated task are synchronized through Web Service. Firstly, task ID is retrieved from changes history table. Using this ID, actual changed are fetched from SQLite DB and sent over Web Service to the server side ADF BC for update. Once all the changes are synchronised, local changes history is cleared:


Web Service call to update data through ADF BC is done programmatically, using MAF mobile helper class AdfmfJavaUtilities. We are constructing list of parameters with names, values and types - invoked method even doesn't need to be defined in the Page Definition, it will be referenced directly from the bindings:

Accessing ADF Iterator Binding from Value Change Listener

Tue, 2014-08-19 09:03
This is a quick hint about how to access ADF iterator binding from value change listener method. Let's say you have generic value change listener, reusable with any kind of input components and you want to get information about underlying ADF BC View Object structure in that listener. Value Change Listener provides access to UI Component, we should evaluate component expression and look up in the bindings for component binding name.

Here is the sample application - ADFIteratorAccessApp.zip. This applications comes with generic value change listener method implemented in the bean. I'm getting value property expression of input component and translating it into attribute name. With the attribute name, I can search in the binding container for attribute binding. From the attribute binding, is possible to retrieve mapped iterator object, iterator could provide information about ADF BC View Object structure:


It works pretty smooth, when generic value change listener is attached to the input component and user is changing value:


Iterator name is printed from generic value change listener, iterator object is retrieved dynamically through attribute definition mapping to iterator:

Data Caching Implementation for ADF Mobile MAF Application

Tue, 2014-08-12 13:19
If you are building mobile application with web service call integration, you must take into account data caching strategy. Without data caching, mobile application will try to establish too many connections with the server - this will use a lot of bandwidth and slow down mobile application performance. This post will be focused around the scenario of implementing simple data caching strategy. In my next post, I'm planning to review MAF persistence framework from Steven Davelaar - this framework is powerful and flexible. Simple data caching strategy makes sense for smaller use cases, when we don't need to use additional framework for persistence.

Data caching implementation in the sample application - MAFMobileLocalApp_v3.zip, is based on SQLite database local to the mobile application. The whole idea is pretty straightforward, there is a database and Web Service publishing data. Mobile application is reading and synchronising data through Web Service. Once data is fetched from the Web Service, it is stored in local cache, implemented by SQLite DB. For the subsequent requests, mobile application is going to use a cache, until user will decide when he wants to synchronise data from Web Service:


Sample application implements a Web Service, based on ADF BC module. This Web Service returns Tasks data (SQL script is included with the sample application):


Besides fetching the data, Web Service implements Task update method:


On the mobile application side, use case is implemented with a single Task Flow. Task list displays a list of tasks, user can edit a task and submit changes through Web Service. This change is immediately synchronised with local cache storage. User is able to refresh a list of tasks and synchronise it with a Web Service. During synchronisation it will clear local cache and populate again with the data returned from Web Service:


Data caching logic is handle in TaskDC class, Data Control is generated on top of this class, this makes it available through the bindings layer. Initially we check if cache is empty and load data from the Web Service, for the subsequent requests data is loaded from cache. Unless user wants to synchronise with Web Service and invokes refresh:


There is a method responsible for fetching data from Web Service and translating it to the Task list structure:


Data from cache retrieval is implemented in the separate method, we are querying data from local SQLite database:


When request hits TaskDC Data Control, we are checking if there are any rows in cache. If there are rows, call to Web Service is not made and rows are fetched from cache:


When user is synchronising with the Web Service, cache is cleared up and re-populated with the rows fetched from Web Service:


Update is synchronised with local cache, so there is no need to re-fetch entire data collection from Web Service:


If the local cache is empty and Web Service is invoked to fetch data, we can see this is Web Service log - it executes SQL. Later call to Web Service is not made, data loaded locally from SQLite database:


We can track update operation on the server side as well, Task details are updated using Task Id:


Initial load for the task list, this is what you should see if Web Service and MAF mobile applications runs correctly:


User could open specific task and edit task properties - changing status:


Task description could be modified:


All changes are saved through Web Service call and immediately synchronised with local SQLite database:


Selected task is updated, user is returned back to the list of tasks:


We could simulate data update on the server, lets change status for one of the tasks:


With refresh option invoked, data is synchronised on the mobile application side and local cache gets refreshed:

ADF Thematic Map in ADF 12c (12.1.3)

Thu, 2014-08-07 12:03
ADF Thematic Map component from DVT library was updated in ADF 12c with marker zoom option and area layer styling (ADF 12c (12.1.3) new features). I have decided to check how it works and implemented quick sample application - ThematicMapApp.zip.

I was using world GDP data (SQL script is available together with sample application) and displayed it using ADF Thematic Map. World country borders are hidden on purpose, borders are visible by default:


While zooming, marker points are growing - very useful feature:


Data for thematic map is fetched using SQL based VO. I'm calculating total GDP and taking percentage from total for the country, this allows to scale marker points better:


ADF Thematic Map is configured to support zooming for markers:


Countries area layer is set to be hidden, although data is still gets attached to the countries:


Marker is configured with dynamic scaling, this is how each country gets appropriate marker size, based on its GDP value:


Marker colour property is set to be dynamically calculated in marker Attribute Groups section:

Standard ADF BC Passivation/Activation for Transient View Object

Tue, 2014-08-05 15:20
If you want to implement transient View Object in ADF BC, you must make sure it will be passivation/activation ready, otherwise you may loose data. There are several ways how to achieve passivation/activation for such View Objects - override passivation/activation lifecycle and handle transient View Object rows programmatically or reinitialise transient View Object rows from Application Module prepareSession method. There is one more solution, I'm going to describe it in this post. It is based on dummy SQL based View Object, designed to to store transient attribute values.

Sample application - ADFTransientVOPassivationApp.zip, implements SQL based View Object with transient attributes. Instead of creating completely programmatic View Object, I have created SQL based with single Id attribute based on SQL expression and added transient attributes. This Id attribute is actually never used, it is there just for only reason - to simulate SQL based View Object. As a key attribute is selected one of the transient attributes:


SQL query doesn't fetch any rows, I'm using it only for a single reason - to simulate SQL based View Object. ADF BC knows how to passivate/activate SQL based View Objects automatically, so I'm going to use this feature and force passivation/activation for all transient attributes created for the same View Object:


Just make sure to select Passivate Including All Transient Values option, this will ensure all transient attributes will be passivates/activated automatically, without any coding intervention:


I'm going to test sample application with AM pooling off, this would simulate passivation/activation behaviour for each request:


On ADF UI side, I'm going to implement a table. To be able to enter rows successfully, for such SQL based View Object with transient attributes, I must enable ChangeEventPolicy = ppr option in Page Definition for the iterator:


Input components must be set with AutoSubmit = true option:


On runtime, when I enter rows, all data gets passivated - you can see this from the log. Three rows are entered, data for all attributes gets passivated/activated automatically:

Handling Rollback Operation for ADF Input Components with Immediate Property

Sun, 2014-08-03 02:44
One of my colleagues is implementing advanced dynamic ADF BC/ADF UI functionality. To force validation to be invoked properly, he must use ADF UI input components set with Immediate=true property. This allows to keep validation messages always displayed, even if user navigates to edit another dynamic ADF UI input attribute, until form is submitted or canceled. However, as by JSF design - usage of input components with Immediate=true, blocks execution of command components, if there are validation errors available. This means - user can't use Cancel button to reset the form with validation errors, until he would fix these errors manually. However, there is a potential solution - we could use ADF subform component to isolate input components, with a combination of ADF View reload to refresh rendered UI.

Sample application - ADFAttributeImmediateApp.zip, implements  basic ADF Panel Form Layout with a set of input components. Each of these input components is set with Immediate=true property:


Let's say there is validation error on the screen for input text component with Immediate=true property:


Try to press Cancel button - no action will happen, it will continue complaining about validation error:


This is how it supposed to be - by default, Cancel button will not be invoked, because Immediate=true validation from input component would block it. We could improve it and adjust for our specific scenario to make sure Cancel button will be invoked, even with validation errors on the screen. We should surround input components with ADF subform component, this allows to isolate from Cancel command:


Cancel button must stay out of ADF subform, this will make it possible to invoke Cancel action listener method, even with immediate input components available on the same screen (but surrounded with ADF subform):


Action Listener for Cancel button gets invoked and reset happens now, no matter if there is validation error for input component with Immediate=true:


There is one extra bit - even with Rollback operation executed, UI would stay unsynchronised and keep displaying validation message until next submit. It requires to force ADF view refresh - you should recreate ADF view programmatically from the same method, where you are invoking Rollback operation:

Oracle BPM 12c Installation Improvements and Issues with Mac

Sat, 2014-07-26 10:13
Oracle BPM 12c is improved with a great installation process - simplified and stable. You only need to download single installation package, run a wizard and after several clicks it gets installed. All required products are installed for you out of the box, no extra configuration is needed - JDeveloper, BPM/SOA extensions, BPM/SOA schemas in Java DB. Developer can focus on his development tasks, no need to spend days to install and configure development environment. You should read official guide - Quick Start for Oracle Business Process Management Suite.

Installer works on Mac OS platform, you can install entire Oracle BPM 12c infrastructure and run domain. However, it fails to open Human Task wizard, while running JDEV on Mac OS. I have developed extremely basic Oracle BPM 12c sample application, to test Human Task wizard with JDeveloper installed on Oracle Enterprise Linux and on Mac OS - BpmApplication.zip.

It works fine to load Human Task wizard with JDeveloper 12c installed on Linux:


The same Human Task fails to open with JDeveloper 12c installed on Mac OS. There is Null Pointer exception generated, thrown from JDeveloper IDE class:


Messages in JDeveloper log for this exception:


Probably you should not use Oracle BPM 12c for development on Mac OS, rather use Linux or Windows platforms. This is a bit pity, but on other hand JDeveloper extensions (except ADF Mobile) always had issues running on Mac OS. It should be no difference, but it seems like development on Linux or Windows with JDeveloper is more stable.

MDS Support for Mobile Application Framework (MAF) in JDeveloper 12c (12.1.3)

Fri, 2014-07-25 06:27
MAF framework in JDeveloper 12c (12.1.3) comes with MDS support. This means, we can customise mobile applications in similar way as we customise regular ADF Web applications. I'm going to explain and demonstrate with the sample application, how it works in MAF 2.0. You can read about it more in MAF 2.0 developer guide, Customizing MAF AMX Application Feature Artifacts.

Sample application, tested with iOS platform - MAFMobileLocalApp_v2.zip. Original version of this application brings Locations screen, where both City Name and Street Address are displayed:


We are going to customise original application with MDS, without changing source code directly. Customized application is based on two MDS tip layers - gold and silver level partners. Gold level partners are able to see State Name in addition to the Street Address:


While silver level partners are allowed to see only City Name:


To achieve MDS functionality behaviour for MAF application, you must define first MDS customisation class, this class must extend from standard MDS CustomizationClass and implement several methods. Important method is getName(), you must define MDS customisation name, the same name will be used for customisation (JDeveloper automatically reads this name during MAF application design time):


Customization class must be set in add-config.xml MDS section, in order to be registered for customisation use:


Once customisation class is registered, we can switch JDeveloper to the Customization Developer mode and start customizing application:


Make sure MDS layers are properly configured in CustomizationLayerValues.xml file. Customization layer must be set to the same name as you set in Customization class above. Layer values should specify different layers supported for customization:


I have defined two layers - gold and silver partnership. MDS layer can be selected for customisation, we start from Gold:


Locations page is updated to include State Name:


However, actual change is stored not in Location page, but in generated MDS file for Location page - it keeps delta for the changes made in customization mode. This file is generated under Gold Partnership profile folder:


State Name addition required to update Page Definition file for Locations, there is extra MDS file created with delta information for Locations Page Definition:


Next we can customize for Silver layer - change layer value:


Here we should keep only City Name and remove Street Address:


This change is reflected in MDS delta for Locations page, stored under Silver Partnership level:

Red Samurai ADF Performance Audit Tool v 3.2 - Large Fetch and Full Scan Audit Optimizations

Fri, 2014-07-18 10:05
Red Samurai ADF Performance Audit tool was updated with new features. Current update v 3.2 is focused on improvements for Large Fetch issues auditing, additionally we are able to track Full Scans (when user is fetching all rows and row count exceeds a threshold).

There are two additional threshold parameters introduced - WAT (Wait Activation Time) and WFT (Wait Fetch Time). These two are used to track long activation and fetch times in more accurate way. For simplified migration process from v 3.1, if no configuration is set in the database - default values are applied:


Large Fetch issue reports time it took to fetch rows, before it was reported only a number of rows fetched:


Audit tool knows how to track Full Scan - issue when user is fetching all rows and number of fetched rows exceeds Large Fetch threshold. This is useful, as it allows to understand specific cases, where we could optimise ADF code and potentially avoid fetching all rows:


Full Scan is reported together with all other issues, it is included to be a part of Performance Analysis graph:


Slow Query drill down was updated, to display VO instances with most recent slow query issues first (in red - number of issues in the recent 5 days):


Table with most recent Slow Query issues was redesigned to display issues in better ordered way. Today issues are displayed first, then issues from Yesterday, followed by Latest in 5 days and then All issues. Average time for each slow VO instance is calculated and displayed:


Daily Trend for VO instance was introduced in v 3.1, now tool also supports Monthly Trend - this allows to understand performance tuning impact better:


Large Fetch drill down was updated, it displays proportion of Large Fetch and Full Scan issues. List of VO instances reported with Large Fetch issues is redesigned in the similar way as for the Slow Query:


Today, Yesterday, Latest (5 days), and All issues are displayed. Average time is calculated and displayed for VO instance large fetch. Monthly Trend is calculated in the similar way as for the Slow Query.

Graphs displaying large number of days are configured with zooming - Daily Transactions and Logged Users graphs support zooming now:


User can zoom in data, this helps to analyse data points in specific days:

ADF Mobile 12c (MAF) Support for Master-Detail Data Control

Thu, 2014-07-17 14:15
ADF 12c is shipped with renamed mobile platform framework - Oracle Mobile Application Framework (MAF). Previously this was named ADF Mobile. 12c MAF is based on ADF Mobile and provides additional functionality and improvements. Everyone familiar with ADF Mobile 11g, should get up to speed with 12c without issues. I would like to highlight one interesting improvement implemented in 12c MAF - out of the box support for Master-Detail relationship. In previous 11g release, master record key was not preserved across different pages - developer was forced to store selected key in memory, to call execute method through invoke action in the second page and finally to reset a key. There was an alternative solution, described by Steven Davelaar - ADF Mobile – Preserving the Current Row Across Pages. Approach described in Steven's blog seems to be integrated into 12c MAF, there is no need to manage selected Master key manually, framework does this for you.

Sample application - MAFMobileLocalApp.zip, is based on HR schema loaded into local SQLite database and implements 2 level Details. Top Master is a Region:


First Detail screen brings a list of all Countries, from selected Region:


Second Detail screen displays available Locations, from selected Country:


Sample application provides navigation springboard, now there is only one Task Flow available - Address (may be there will be more options in the future):


Overall, 12c MAF is a great step forward - improved performance, better and cleaner UI, new features. MDS Seeded Customizations are supported now for mobile applications implemented with 12c MAF.

Sample comes with HR schema structure and data:


HR structure and data is loaded to the local SQLite database on initial application startup:


SQLite database is a physical file and we are opening JDBC connection. This is a database for single user, one user will be using it - no concurrency:


I will describe below, how to create Master-Detail structure and generate Data Control. There is a special extension available for similar task - A-Team Mobile Persistence Extension for Oracle MAF. However, for this exercise I would like to do it myself.

Firstly we should start with a model. There is Master-Detail relationship between Regions and Countries. Region object included a list of Country objects:


Country object in turn includes a list of Location objects, this is 2nd dependency:


This is our basic model, nothing complex. Model needs to be populated with data, this can be done with SQL, as all our data is stored locally in SQLite DB. Region, Country and Location rows are retrieved using SQL, Master-Detail relationship is populated manually:


Master-Detail relationship would not work, if there would be no Primary Key defined for Master object. By default, key is not set, when Data Control is generated. We need to edit Data Control object explicitly:


Here we can set a Primary Key for the attribute:


Task Flow displays relationship between Regions -> Countries -> Locations, there must be Primary Key set at least for Regions and Countries:


Important rule to know, 12c MAF doesn't really remembers current row in Data Control - it rather searching for iterator name and retrieves current state. This means, iterators in different pages must have the same names, otherwise current row key will not be resolved (even for the same data model object).

As for example, Region fragment:


Is based on data retrieved from regionsIterator:


This means Country fragment, displaying detail data:


Must have reference to Master iterator with the same name, as it is created in the first page Region (regionsIterator):

ADF 12c (12.1.3) Line Chart Overview Feature

Sat, 2014-07-12 10:51
ADF 12c (12.1.3) is shipped with completely rewritten DVT components, there are no graphs anymore - they are called charts now. But there are much more, besides only a name change. Previous DVT components are still running fine, but JDeveloper wizards are not supporting them anymore. You should check ADF 12c (12.1.3) developer guide for more details, in this post I will focus on line chart overview feature. You should keep in mind, new DVT chart components do not work well with Google Chrome v.35 browser (supposed to be fixed in Google Chrome v.36) - check JDeveloper 12c (12.1.3) release notes.

Sample application - ADF12DvtApp.zip, is based on Employees data and displays line chart for the employee salary, based on his job. Two additional lines are displayed for maximum and minimum job salaries:


Line chart is configured with zooming and overview support. User can change overview window and zoom into specific area:


This helps a lot to analyse charts with large number of data points on X axis. User can zoom into peaks and analyse data range:


One important hint about new DVT charts - components should stretch automatically. Keep in mind -parent component (surrounding DVT chart) should be stretchable. As you can see, I have set type = 'stretch' for panel box, surrounding line chart:


Previous DVT graphs had special binding elements in Page Definition, new DVT charts are using regular table bindings - nothing extra:


Line chart in the sample application is configured with zooming and scrolling (there are different modes available - live, on demand with delay):


Overview feature is quite simple to enable - it is enough to add DVT overview tag to the line chart, and it works:

ADF 12c (12.1.3) New Feature - ADF Query Item Reordering and Custom Operators

Thu, 2014-07-10 01:21
There are quite many new features in ADF 12c (12.1.3). One of them - ADF Query item reordering on runtime, user can choose the order to display criteria items displayed in ADF Query. View Criteria wizard in JDeveloper is updated, besides Criteria UI Hints (as we had before), now developer have access to Item UI Hints (here you can set item visibility, multiple values selection and removable support). Important addition - new tab in the wizard to define and manage Custom Operators for View Criteria items (this was possible before directly in the source code, now we have a wizard).

Here you can see new View Criteria wizard in ADF 12c (12.1.3) with UI Hints tab for each criteria item. I have set First Name criteria item to be rendered only in Advanced mode, also with removable option:


Custom Operators tab allows to create new operator or update/remove existing one, very useful feature to manage criteria search options:


ADF Query UI remains unchanged (by the way, First Name is not rendered in basic mode as it should):


Go to advanced mode - First Name is rendered now. There is additional button - Reorder. New functionality in ADF Query 12c (12.1.3):


Reorder brings a popup with ADF Query items, user can move Email to be the first item:


ADF Query is updated with the change - Email item is the first:


Even after returning to basic mode - order remains. I believe this will be quite useful functionality, especially for large ADF Query blocks with many criteria items:


Download sample application - ADF12cQueryApp.zip.

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.