Friday, May 31, 2013

New ADF Academy - Impressive Concept for ADF eLearning

There is new free ADF eLearning material available from Oracle - ADF Academy delivered online and available to anyone. You can access and learn from the first published course - Developing Applications with ADF Mobile.

One of the great things about this material - different technical resources are collected into one single place. Plus interactive way of viewing these video/audio resources makes ADF learning real fun !


Thursday, May 30, 2013

ADF Fragment Data Reload with Poll Component

If you are looking for simple but effective solution to refresh data in ADF, you might be interested to check ADF Poll component. This component integrates well with ADF fragments - reload event is isolated in the scope of fragment and not distributed to entire page, means whole page will not be refreshed, but only fragment. I will demo this below with example.

Sample application with ADF Poll component configured to refresh Employees table only - ADFPollFragmentApp.zip.

Employees fragment implements ADF table and Poll components:


Poll is set to initiate reload event every 5 seconds by default. It will stop sending reload events after 600000 seconds. PollListener is defined to implement reload logic:


PollListener re-executes VO SQL for the table and at the end sends Partial Trigger event to perform visual refresh for the Panel Collection UI component containing table with Employees data:


VO is re-executed by accessing iterator bindings from Page Definition:


Main page includes ADF region where Poll component is configured and additionally it contains another table component. There is one more table included to prove that data reload event is not distributed outside of the fragment:


We can see how it works. Open Departments tab from the main page, where no Poll component is configured and select any row from the table - remember your selection, we are going to check it later:


Go to the Employees tab and there check current salary value for Lex De Haan employee. Salary value is 17007:


Open database table and change salary value for the same employee to be 1500, commit your changes:


Switch back to page and you will see that during next data reload Poll event - change will be fetched to the UI:


Similar if you create new record and commit it in the database:


This record will appear in the UI automatically for you:


If you go to Departments, previously selected row still remains correct - this means Poll component was distributing reload event only in the scope of the fragment:

Sunday, May 26, 2013

Customized BPM 11g PS6 Workspace Application

I'm quite often using customized BPM 11g workspace application integrated into ADF 11g custom application. You can download it for BPM 11g PS5 from my previous blog: Tips & Tricks How to Run Oracle BPM 11g PS5 Workspace from Custom ADF 11g Application. Standard BPM 11g workspace ADF task flow is customized with MDS - ADF 11g PS5 Application with Customized BPM Worklist Task Flow (MDS Seeded Customization). I would like to present today updated workspace application to BPM 11g PS6. The reason to migrate customized BPM workspace to PS6 was because I'm often using it during ADF/BPM integration trainings. Also I will be posting future posts in ADF/BPM integration area based on upgraded PS6 sample application.

Here you can download new sample tested with BPM 11g PS6 - adfbpmapp_ps6.zip. ADF 11g PS6 comes with new look&feel - new ADF skin Skyros. New ADF skin and updated UI layout gives new look for BPM 11g workspace ADF task flow. Workspace ADF task flow shipped with BPM 11g PS6 release is lighter, works faster and looks better. Do you see Register button next to task list? This is custom button added through MDS customization:


You can see that user is given option to initiate new BPM process, view list of tasks assigned and finally access Human Task form. Human Task form for different steps is implemented using Generic Human Task Handler concept - Generic ADF 11g Human Task Handler Concept for Oracle BPM.

Sample application comes with BPM process. Once user redsam1 submits his task for further processing, task gets assigned for redsam2 user:


User redsam2 is granted access to the workspace, based on configured ADF Security settings, date is rendered as readonly. Data is fetched from DB based on process key:


If user redsam2 approves selected task, process steps are marked as completed:

Monday, May 20, 2013

Custom Transaction Factory in ADF BC for After Commit

We were facing issues overriding Custom Transaction Factory in ADF 11g R1, it was initialized only for the first loaded AM, this seems is not the case anymore in ADF 11g R2 (11.1.2.x). I would like to present today a use case of implementing global after commit call. Read more about use cases with Custom Transaction Factory in ADF Developer Guide - 12.8 Customizing Business Components Error Messages.

Sample application - CustomDBTransactionApp.zip is based on two separate AM's:


First AM is configured with Custom Transaction Factory:


Second AM is configured with Custom Transaction Factory:


Referenced Transaction Factory class creates new instance of DB Transaction implementation, where commit() and doCommit() methods are overriden:


You can see that message is printed after calling super in both cases:


If you want to execute code after commit operation was completed, you should call it after super in commit() method. This will be called one single time after commit, for all EO's at once.

In addition I have overriden doDML and afterCommit methods available in EO implementation to compare invocation time. Obviously these methods will be invoked separately for each EO:


We can test it now. Edit data from the first AM and commit transaction with Save button:


Check the log - first it starts executing SQL update statement. It calls doDML() method from EO implementation, next it calls doCommit() method from Transaction Factory, right before DB commit it calls afterCommit() method from EO implementation and finally after DB commit - commit() method from Transaction factory (after calling super) is called. This means afterCommit() method from EO is really invoked after data was posted to DB, but not after actual DB commit. In contrast, after super in Transaction Factory commit(), we can call custom logic and it will be executed after DB commit:


Test the same for the second AM:


It does same logic as for the first AM, you can check it applies correct AM instance:

Thursday, May 16, 2013

New Row Delete for ADF Form (ADF Webinar Follow-Up)

There was a question on ADF Masterclass Webinar (Video: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)) about removing new row from ADF Form. I have a blog post about removing new row from ADF table - Immediately Removing New Row Without Validation in ADF, but one of the Webinar participants was saying the same doesn't work for ADF Form layout component. I promised to double check this and post sample application.

Here you can download sample application - NewRowRemoveApp_v2.zip. So, the main trick is additionally to setting Immediate=true for Delete button, add ADF resetActionListener operation to the same Delete button:


Make sure Immediate=true is set for Delete button, along with ADF resetActionListener:


Add new row, force validation errors by trying to navigate to the next row:


Press Delete button to remove new row, validation errors will be ignored and row will be removed:


For ADF Form component is not enough to set Immediate=true property only, ADF resetActionListener must be added to force form refresh.

Wednesday, May 15, 2013

Grant Ronald and Susan Duncan for ADF Mobile SIG (UKOUG, London, May 21st)

ADF Mobile is one of the hot topics in ADF area currently. If you want to see it in practice and learn about ADF Mobile architecture, I'm sure you should join UKOUG SIG in London on May 21st. Check here for more info and registration link - UKOUG Run Full Day SIG on ADF Mobile.

Grant Ronald and Susan Duncan are well known Oracle speakers, they will host this event. I know there are few seats left, you should hurry to register.

Video: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)

I was blogging about ADF for 7 years already, long period. I had a feeling this was a right time to bring it to the next level and have live technical ADF Q&A discussion with blog readers. It went well and I plan to repeat similar session later this year again. Read more here: Webinar: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)

You can watch video recording:



Webinar plan with links to use case descriptions and presented ADF sample apps from the blog:

1. CRUD and LOV performance and validation improvement tricks

- List Range Size - 1 for LOV

(LOVRangePagingFix: http://andrejusb.blogspot.com/2011/12/fix-rowset-is-forward-only-for-adf-bc.html)

- Row Count Threshold -1

(QueryOptimizationTableApp: http://andrejusb.blogspot.com/2012/05/how-to-disable-select-count-execution.html)

- Initial Query Overriden

- Skip Validation

(TabsValidationApp: http://andrejusb.blogspot.com/2012/12/skip-validation-for-adf-required-tabs.html)

(NewRowRemoveApp: http://andrejusb.blogspot.com/2013/01/immediately-removing-new-row-without.html)

- Immediate Validation for table

(AutoPPRApp: http://andrejusb.blogspot.com/2012/09/what-to-do-when-adf-editable-table.html)

- Post Changes

(PostControlApp: http://andrejusb.blogspot.com/2012/12/adf-post-changes-and-plsql-invocation.html)

2. Conditional validation in ADF BC, Entity Cache and View Object Instances

- Conditional

(ConditionalValidationApp: http://andrejusb.blogspot.com/2012/12/conditional-validation-in-adf-bc.html)

- Transaction level

(EOValidationApp: http://andrejusb.blogspot.com/2012/10/transaction-level-adf-bc-entity.html)

- EO Cache

(VOSynchEOCacheApp: http://andrejusb.blogspot.com/2013/05/sharing-data-between-vo-instances-in.html)

3. ADF Table pagination, List View components

- Pagination

(TablePaginationApp_v3: http://andrejusb.blogspot.com/2013/04/how-to-control-adf-table-pagination-on.html)

- List View

(ListViewApp: http://andrejusb.blogspot.com/2013/04/list-view-cool-looking-adf-ps6.html)

4. ADF Mobile login, secured ADF BC Web Services and on-device database access

- Mobile login

(adfmobilelogin: http://andrejusb.blogspot.com/2012/10/adf-mobile-login-functionality.html)

- Secured WS access

(mobilesecuredws: http://andrejusb.blogspot.com/2012/11/adf-mobile-secured-web-service-access.html)

- Master-Detail

(adfmdmobilews: http://andrejusb.blogspot.com/2013/04/master-detail-adf-bc-web-service-for.html)

Thursday, May 9, 2013

Sharing Data Between VO Instances in ADF BC

Probably you already noticed that by default data is shared between VO instances (or even separate VO's) based on the same EO. Newly inserted row into one instance becomes instantly visible from another VO instance. There is a way to control this behavior in ADF, this post is based on excellent Steve Muench source of information - Using the RowQualifies() Method to Fine Tune View Link Consistency Behavior. As Steve says, by default data is shared and you can turn it off either by calling setAssociationConsistent(false) or globally per AM with jbo.viewlink.consistent=false configuration property:


Idea of this post is to go a bit deeper and to show how you control data sharing between VO instances programmatically. For example how to delay new row sharing between VO instances until this row is commited.

Sample application - VOSynchEOCacheApp.zip, contains one EO and one VO for Employees:


There are two VO instances defined in AM out of Employees:


Two fragments are implemented in ADF Controller. First displays data from EmployeesEditView and allows to insert new row. While second displays a table with data from EmployeesListView:


We create now new row in the first fragment:


Navigate to the second fragment with the table. Keep in mind - new row is not commited yet, it is just inserted into EmployeesEditView VO instance. However, as per default behavior data is shared between VO's and this new row is appearing in the list from EmployeesListView VO instance:


In order to control when newly inserted row is shared between VO instances, we can override rowQualifies method from VO Implementation as per Steve Muench suggestion above. We have access to the row and can check row status. In this example row is qualified to be added into rowset if its status is unmodified:


Test now again the same scenario - try to insert new row, but don't commit yet:


Navigate to the second fragment with list data - new row is not added yet as expected:


Go back and save new row:


You can check it will be added to the rowset now and displayed in the list from second VO instance:

Saturday, May 4, 2013

JDeveloper 11g (11.1.2.4.0) Startup Mystery - JDK 1.6.0_24 Not Supported (1.6.0_35 Required)

New JDeveloper 11g (11.1.2.4.0) on Windows fails to start with embarrassing error after fresh installation, this is known issue and Oracle is fixing it. Seems like Oracle engineers missed it and released JDeveloper 11g (11.1.2.4) with wrong JDK. Once you install JDeveloper 11g (11.1.2.4.0) and try to start it, JDK error is reported - Java version 1.6.0_24 not supported. The minimum version required is 1.6.0_35 and JDEV startup stops, basically unusable:


If you go and check installation contents for JDeveloper 11g (11.1.2.4.0), you will see only JDK 1.6.0_24 packaged. This looks like a mistake to me:


Workaround (until Oracle will fix it in JDeveloper 11g (11.1.2.4.0)) is to install required JDK 1.6.0_35 manually by yourself and point it during JDEV startup:


With manually installed JDK 1.6.0_35 JDEV works:


Still this is quite funny - why JDK 1.6.0_24 would be included if JDEV requires JDK version 1.6.0_35.

Thursday, May 2, 2013

Duplicate Validation Error Message and ADF Bindings

One of the bug requests I was fixing during this week was related to duplicate validation error message display on ADF UI. This was quite annoying to the users - the same validation error message displayed twice:


There was nothing special about this validation rule, as any other validation rule defined on ADF BC Entity Object:


I noticed something strange in Page Definition file. As per screenshot above, ADF UI renders only table component. However, in Page Definition file table binding was defined along with attribute binding for the Salary attribute:


Salary in the table is rendered from table binding, and as additionally we have attribute binding for the same element, this is causing the same validation error message reported twice (one for Salary in the table binding and another for Salary attribute binding):


Make sure not to leave duplicate bindings for the same attributes:


It reports only one validation error message, as expected:

Here you can download sample application with duplicate validation error message, try to fix it as described in this post - ADFValidationErrorApp.zip.