Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 14 hours 32 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 -

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 -

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 -

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 - 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: