Saturday, August 31, 2013

ADF Task Flow Template Improvements in 12c

There are great improvements in ADF task flow templates in 12c release. We can use ADF task flow template based on other template and what is even more amazing - JDeveloper 12c ADF task flow diagram window displays template contents when editing actual consuming task flow. There is option to substitute activity in the consuming ADF task flow for the generic activity from the template. I'm going to explain how you can do this.

Here is sample application for ADF task flow template in 12c - TaskFlowTemplateApp.zip. This application implements following ADF task flow template:


As you can see template contains generic router activity - it check how task flow should be loaded and if new row should be inserted. There are method calls for Commit and Rollback operations, meaning no need to add Commit and Rollback operations into Page Definition, will be called directly from the task flow. Activity - fragmentView is defined, but not created, we are going to substitute if the real fragment a bit later in the consuming task flow.

There are three page definitions created for activities in the template: create, commit and rollback operations:


We can create our task flow, based on available ADF task flow template:


Here you can see 12c new feature - task flow editor displays contents from the template. This is amazing and very useful feature:


All the activities can be reused from the template. Only page fragment is substituted with the real one, meaning every consuming task flow can have its own fragment. In order to substitute the fragment you need to go to the source code mode and override activity ID from the template (fragmentView in this example) pointing to fragment you want to load in this particular ADF task flow:


Fragment can be created in the same way as in ADF 11g:


Page is loaded and user can commit/rollback through generic activity methods implemented in the ADF task flow template:

Wednesday, August 28, 2013

ADF 12c - Target Tag to Enhance PPR Rendering

There is new tag in ADF 12c called target. This tag in some use cases can substitute PPR dependencies effectively and help to avoid unwanted validation errors in data entry process. More about this tag you can read from ADF Faces 12c documentation - 8.3 Using the Target Tag to Execute PPR.

I will demo use case of LOV and dependent mandatory input text field. Selected value from LOV should update mandatory text value. With ADF 11g PPR dependency you will get validation error for required field, before LOV will be loaded - since LOV will try to refresh dependent input text even on load, not only during return.

Here you can see typical PPR dependency between LOV and input field. LOV is set with auto submit and there is partial trigger specified for input text:


We insert new row to make all fields to be blank:


Try to open LOV, validation error for dependent mandatory field will be displayed:


Let's use target tag as per documentation referenced in above link. There is no need to set auto submit and partial trigger dependencies. Only define target tag to be applied for LOV and render changes in text field:


LOV opens without triggering validation errors in required field:


Selected value is returned from LOV and set for dependent text field automatically:


Placeholder - another new feature in ADF Faces 12c. We can provide help text describing empty field:


This is just another property for the input text component:


Download sample application - TargetRefreshApp.zip.

Thursday, August 22, 2013

ADF Essentials 12c ADF BC 'BO_SP' ORA-01086 Error

It seems like there are differences running same ADF application on WebLogic and on Glassfish runtime. These differences are minor but could cause some headache to the developers. In this particular case, I would like to describe ORA-01086: savepoint 'BO-SP' never established error. Typically this error could happen, if PS_TXN table is unavailable. However, this is not the case with ADF Essentials 12c - PS_TXN table exists and application is able to access it. 'BO_SP' error is generated when DB constraint is triggered, instead of returning DB error message - ADF Essentials 12c displays ORA-01086: savepoint 'BO-SP' never established error.

How to reproduce: set Salary attribute value to -1, there is constraint in the DB to check for positive values. Constraint is invoked, but instead of getting constraint message - 'BO_SP' error happens:


Workaround is to enable DB pooling for the Application Module, by setting Disconnect Application Module Upon Release property:


This is recommended setting for ADF BC performance and Data Source connections usage optimization: Stress Testing Oracle ADF BC Applications - Do Connection Pooling and TXN Disconnect Level. Is hard to say why exactly setting DB pooling fixes 'BO_SP' error for ADF Essentials 12c, I guess is related to DB driver used in Glassfish. With DB pooling enabled, DB connection is released after request - perhaps this allows to avoid rolling back transaction to BO_SP and in turn fixes the error.

DB constraint is displayed correctly with DB pooling enabled:


Download sample application - ListViewAppEssentials.zip.

Wednesday, August 21, 2013

ADF BC Locking Lifetime and Application Module Pooling

ADF BC API provides method to lock current row, but lock lifetime can be short. Lock method issues SQL lock and locks the record for current user. If your use case is to keep lock for longer period of time, in other words to reserve record by the user until commit or rollback - this is not the method you should use. Lock issued from ADF BC can be released automatically, before user will be committing his changes. This happens when DB pooling is enabled or when there are more concurrent users than AM pool can handle. If you want to make sure that record will be reserved by the user for certain period of time, you must implement custom flag column in the DB and update it separately.

In this post I will demo, why you should avoid using ADF BC lock method to reserve current row by the user. Here you can download sample application - LockApp.zip.

VO implements a custom method exposed to the Data Control, where ADF BC API lock() method is called for current row - this issues SQL lock in the DB for current row:


User A opens ADF form, selects record with ID = 102 and invokes our method to lock the record:


We can see SQL statement executed in the DB - lock is set successfully:


User B opens ADF form, selects record with ID = 102 and invokes lock method - error is generated. Since user A still holds a lock:


We can see this from SQL log - lock attempt was not successful:


Lock remains for user A only in perfect scenario. In real life, when more users will be accessing your system, at some point AM pooling will start working and AM instances will be switching between users. When AM instance is switched, DB connection is reset and current lock will be lost.

In order to simulate loosing of lock, I set Referenced Pool Size = 1. This means AM will support only 1 user, if there will be more users - AM pooling will be working and AM instance will be shared between users:


User B can set a lock now, even before user A releases his lock. This means user A will be loosing reserved row before doing a commit/rollback:

Friday, August 16, 2013

WebCenter Portal - New Name for WebCenter Spaces in 11.1.1.8

There is a name change in WebCenter with the recent 11.1.1.8 release. WebCenter Spaces is not a fancy name anymore, Spaces is renamed to Portal. Simply speaking, if you are running Spaces - means you will be running now WebCenter Portal. On other hand, if you are running custom application built with WebCenter Portal Framework - this is also a Portal, just custom made.

WebCenter Portal (previously Spaces) UI is improved in 11.1.1.8 and performance wise is quite well responsive. Here is main login screen:


WebCenter Content access works from WebCenter Portal only if Content Server is configured with Folders_g component, it still doesn't work with new FrameworkFolders:


In terms of UI - all popups are removed from WebCenter Portal interface, this makes UI look cleaner. For example, preferences can be edited now in the same window, without opening separate popup:


There is Portal Builder wizard - central place to import/export and manage portals:


Portal template grouping and description is more user friendly:

Thursday, August 15, 2013

Multiple Choice Support in ADF BC View Criteria

It happened to see while reviewing ADF projects people are using complex implementation to allow search on multiple values. Same is available out of the box, I would like to share with you - may be it will save time during your next use case implementation.

Sample application - ADFQueryMultipleChoiceApp.zip, implements choice list LOV for Job ID attribute:


Job Id attribute is included into View Criteria as search item. Make sure to set search operator as Equals, otherwise LOV will be ignored and simple input text will be rendered:


Still in View Criteria wizard - go to UI Hints tab and make sure to select check box - Support Multiple Value Selection for JobId attribute. This will inform ADF runtime to render multi choice support in ADF query field:


This is how it looks on runtime - we can choose multiple value for Job Id - all them will be added to the query:


Data is filtered accordingly - employees with different Job Id's are included:


On SQL level - each value is added as separate bind variable:


And appended to the SQL statement WHERE clause:

Wednesday, August 14, 2013

ADF Task Flow Transaction Management and ADF Libraries

I received a question from blog reader to check if ADF Task Flow transaction management still works when different Application Modules are coming from ADF libraries. Blog reader had a doubt it will not work. I did a test - it works well, so I would like to share this sample application with you as well.

Sample application - transaction_adf_libs_11g.zip is based on ADF library with Application Module - HrModule:


Reusable Application Module is packaged as ADF library and later imported into main application:


Main application contains second Application Module called HrMainModule:


At the end there are two Data Control entries available, one from local AM and another from imported one:


Both Data Control entries are registered in DataBindings.cpx file:


I have created one container wrapper task flow to launch target task flow with transaction management:


Target task flow contains one fragment (includes data from both Data Controls) and return activity (performs commit):


There will be always new transaction started on task flow entry, commit will be done on task flow level from return activity (see above):


From index page we can launch target task flow and initialise new transaction:


Here we edit data from the first Data Control in the left section:


Also data from the second Data Control in the right section:


Both changes will be saved automatically with single Save button click with ADF Task Flow transaction management. No matter if Data Controls are based on Application Modules from the same application or ADF libraries.