Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 15 hours 47 min ago

Video and Slides - Data Caching Strategies for Oracle Mobile Application Framework

Sat, 2014-10-18 09:08
I have recorded a video tutorial, based on my OOW'14 session - Data Caching Strategies for Oracle Mobile Application Framework. ADF developers who could not attend OOW'14 in San Francisco, this is for you !

Here you can view the slides:

Data Caching Strategies for Oracle Mobile Application Framework
Watch the first part of the tutorial:

Watch the second part of the tutorial:

Described solution is based on the sample application from the blog post - Transactional Data Caching for ADF Mobile MAF Application.

Workaround for ADF 12c Choice List Blank Selection Issue

Sun, 2014-10-12 09:28
I would like to share a workaround for Choice List component in ADF 12c. There is specific issue, related to blank selection - as soon as user selects blank selection in the choice list, it starts to invoke value change listener for that list, each time when any other element is selected in the table. This is quite annoying and could lead to unexpected results, especially if you depend on logic implemented in value change listener.

Workaround is implemented in the sample application - We should take a look first, how it works without workaround applied. Imagine you have a table and one of the columns implements a choice list. Go and select a blank selection for a couple of rows:

Navigate between rows, do couple of clicks - you should notice in the log information about value change listener invoked. This is quite strange, it should not call value change listener each time, just only first time after selection was changed in the list:

Choice list UI component is set with AutoSubmit=true and assigned with value change listener method:

Choice list is configured with blank item selection in ADF BC:

To apply workaround, go and uncheck blank item selection in ADF BC, make sure checkbox for 'Include No Selection Item' is unchecked:

On UI side, provide any value for UnselectedLabel property of the choice list component, this will generate property in the source (alternatively you could just type it manually directly in the source):

Make sure UnselectedLabel property is set to be blank, this will generate blank item on the runtime (it works much better than the one enabled from ADF BC):

User could navigate through the table, there will be no value change listener triggered anymore (besides one time, when value was actually changed):

Exciting as usual - new features and new bugs :)

New Alta UI for ADF UI Shell Application

Tue, 2014-10-07 23:14
I have applied new Alta UI for customised ADF UI Shell application. Customised version of ADF UI Shell is taken from my previous blog post - ADF UI Shell Usability Improvement - Tab Contextual Menu. Old application with new Alta UI looks fresh and clean. Runtime performance is improved - ADF transfers less content to the browser, this makes application load and run faster.

Here you can download my sample application with Alta UI applied to ADF UI Shell -

All three ADF UI Shell tabs are opened and Master-Detail data is displayed in this example:

New style is applied for LOV component and buttons, making all buttons and controls more visible and natural:

Customized ADF UI Shell supports tab menu - user can close current tab or other tabs:

There was a change in 12c related to the tab menu, we need to set align ID property differently. You can see this change in ADF UI Shell template file - Java Script function gets tab ID to align directly from component client ID property:

Alta UI is applied simply by changing a skin name in trinidad file:

This hidden gem was packaged with current JDEV 12.1.3 release, you don't need to download anything extra.

New ADF Alta UI for ADF UI Shell

Mon, 2014-10-06 15:55
New skin for ADF in 12c looks great, I have applied it for one of my sample application with ADF UI Shell and it works smoothly. Check Oracle documentation how to apply Alta UI, really easy.

ADF UI Shell with Alta UI - clean and light:

REST Support for ADF BC in 12c

Thu, 2014-10-02 18:45
Frank Nimphius have announced REST support for ADF BC feature on OOW today. Probably this functionality will be available in the next JDeveloper 12c update release.

Once REST will be enabled for Application Module, new XML definition file and project will be created. Here you can see how new wizard will look like for REST definition on top of ADF BC:

Suppressing ADF LOV Like Operator Filtering

Sat, 2014-09-27 05:05
ADF LOV component provides filtering option with STARTSWITH operation. This is used to check if similar value exists in the LOV, if such value exists - LOV popup is opened with all the suggested values. If user types 10 and there are 100, 1000 in the LOV, instead of accepting value 10 - LOV popup will be opened and all three values 10, 100, 1000 will be displayed. While this is useful, there is no option to turn off such functionality. My post describes a solution, that can be used to disable suggested LOV filtering.

Here you can see, how it works by default. User types 10, there is 100 in the LOV. LOV popup is opened with both suggested values. This can be annoying for advanced user, who already know the code and they don't need to use LOV popup to select it:

We can check generated SQL statement. Original LOV SQL was updated with LIKE and this was applied for bind variable value. This is how suggested LOV values are retrieved:

LIKE is applied for DepartmentID (LOV key), even we have set it explicitly in the LOV View Criteria to use EQUALS operator:

The solution is to override buildViewCriteriaClauses method in VO Impl class. ADF executes additional View Criteria to retrieve suggested LOV values, this criteria name is "__lov__filterlist_vcr___". We can intercept this View Criteria and replace all STARTSWITH operators with EQUALS:

With this fix applied, user could type 10 and there is no LOV popup opened anymore with suggested values:

Same SQL as before is generated, but LIKE is changed to =, this is the result of our fix:

New LOV value can be successfully saved to the DB:

Download  -

ADF Region Data Synchronisation with Change Event Policy

Tue, 2014-09-23 11:30
This post applies for multiple ADF regions, based on the same Data Control. I will show you can avoid using ADF Contextual Events to synchronise two ADF regions, when both are based on the same Data Control and this Data Control is shared between the two.

Sample application contains two ADF Task Flows, both are using the same VO instance from shared Data Control:

Two ADF regions are implemented based on these TF's, one implements table component and another a form:

Data from both regions is synchronised automatically. Based on row selection in the table, form data from another region stays in synch:

Backwards synch works as well - change Salary attribute value in the form:

Salary attribute in the corresponding row from the table will be updated:

In order for this to work, make sure to set ChangeEventPolicy=ppr for Employees iterator in the first fragment page definition (this will ensure update when data is changed in the form and we want to see synch in the table):

Set the same property for the iterator in the second fragment page definition (this will ensure form data to be in synch when row selection is changed in the table):

Download sample application -

JDeveloper 12c ADF View Token Performance Improvement

Sat, 2014-09-20 05:37
There is known limitation in ADF 11g, related to accessing application in the same session from multiple browser tabs. While working with multiple browser tabs, eventually user is going to consume all view tokens, he will get timeout error once he returns back to the previous browser tab. Unused browser tab is producing timeout, because ADF 11g is sharing the same cache of view tokens for all browser tabs in the same session. This means the recent mostly used browser tab is going to consume all view tokens, other browser tab would loose the last token and screen state will be reset. This behaviour is greatly improved in ADF 12c with separate view token cache supported per each browser tab. If your application is designed to allow user access through multiple browser tabs in the same session, you should upgrade to ADF 12c for better performance.

I'm going to post results of a test with 11g and 12c. Firstly I'm going to present ADF 11g case and then ADF 12c.

ADF 11g view token usage:

Sample application contains one regular button, with PartialSubmit=false, to generate new view token on every submit:

Max Tokens parameter in web.xml is set to 2, to simulate token usage:

To see the debug output for view tokens usage on runtime, you should set special parameter - org.apache.myfaces.trinidadinternal.DEBUG_TOKEN_CACHE=true

On runtime try to open two browser tabs. You are going to see two view tokens consumed and reported in the log:

Press Test View Token button in the second tab, this would consume another view token. Remember, we have set maximum two tokens, no in the log it says - removing/adding token. This means, we have consumes both available tokens (for both tabs) and token from the first tab is replaced:

Go back to the first browser tab, try to press the same Test View Token button and you are going to get time out error - view token is lost and you need to reload the tab:

ADF 12c view token usage:

Sample application in the same way as in 11g, also implemented simple button set with PartialSubmit=false. This would force to use new view token on each submit:

Max Tokens parameter in web.xml, again is set to 2:

Two browser tabs are opened and two view tokens are consumed:

Press Test View Token in second browser tab, you are not going to see in the log information about removing/adding token (differently to 11g). This means, view token from the first browser tab still remains in the cache, second browser tab maintains its own view token cache:

Go back to the first browser tab, press Test View Token button - application works fine, no time out error as it was in 11g:

Download sample application ADF 11g and 12c examples -

Handling Format for BigDecimal Numbers in ADF BC

Tue, 2014-09-16 13:12
This may not be as straightforward as it sounds - to define a format for a number attribute in ADF BC. Especially if you are going to have large number (more than 15 digits). Most likely you are going to experience precision/scale and rounding issues, for BigDecimal and Number type attributes with format mask applied. Sounds frustrating? Yes it is. I hope my blog post will help you to implement proper number formatting.

Firstly I'm going to demonstrate, how it works by default. I'm going to use format mask for 18 digits and 2 decimals. Format mask for a number attribute of BigDecimal type would fail with invalid precision/scale error - this is surprising, especially knowing that attribute is defined with (20, 2) precision and scale:

There is one more issue to handle - automatic rounding for large numbers (more than 15 digits). In this example I'm trying to enter a number with 18 digits:

Suddenly number is rounded, immediately after focus is moving out of the field - this is bad, user can't enter correct large number:

Let's see, how we can fix it. I will explain solution, based on Salary attribute with (20, 2) precision and scale. By default, this attribute is generated with BigDecimal type, I'm going to keep the same type, no need to change to oracle.jbo.domain.Number:

I have set format mask on the VO level, for the same Salary attribute. There is another issue - maximum length of the attribute value user can enter on UI. Maximum length property is reading precision and calculates maximum number of characters, however this is wrong when format mask is applied:

There will be extra comma and dot signs coming from the format, so I would advice to set Display Width to be equal to the attribute precision plus maximum number of commas and dots (26 in my case). Later we would need to change maximumLength property on the UI to use Display Width instead of precision:

Once you set a format mask, formatter class name is assigned for the attribute. Formatter class name is saved in resource bundle, for each formatted attribute separately:

You must change formatter class name to the custom one, don't use DefaultNumberFormatter class - out of the box formatter doesn't work with BigDecimals. Sample application comes with custom Number formatter class. Format method is overridden to support BigDecimal, standard formatter method breaks BigDecimal number by converting it to Double (this is the reason for rounding error) - this is fixed in the sample:

Method to parse is changed as well (this is fixing precision/scale number for the BigDecimal). Instead of calling parse method from super, I'm calling custom method:

I'm setting a property to enable BigDecimal parsing, this allows to work correctly with precision/scale:

In addition, precision and scale are checked by custom method - if there is invalid number of digits, user will be informed:

I was mentioning it earlier - maximumLength property on the UI is updated to point to Display Width set on the VO attribute UI Hints:

We can do a test now, type long number with 18 digits (remember (20, 2) precision/scale for Salary attribute):

Correct format will be applied:

Type decimal part and now there will be no error about precision/scale - it will be successfully accepted:

You can see from the log how format is being applied, it works well with custom formatter class provided in the sample application -

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:

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

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