Thursday, November 27, 2008

Workaround for Null Value Bug in ADF List Of Values 11g

Those of you, who are using List Of Values (LOV) component in ADF 11g, most probably already have noticed bug related to Null value. Simple description - if any non Null value is set for LOV, it is impossible to set Null value (for non-mandatory LOV's). This bug is known for Oracle, and I'm sure they will fix it in next build. For now, there are two paths for us. First is to ignore it, and test with next build, when it will be available. Second is to apply temporal workaround, until bug will be fixed by Oracle. In my opinion, you should follow second path, if you have critical need to be able to set Null value for LOV before next build will be available from Oracle. In this post, I will describe this workaround, relatively very simple one.

You can download sample application, with implemented workaround - This sample contains basic form, with one LOV component for DepartmentId attribute:

So, the problem is with Null value in LOV component, basically Null is not accepted. This bug is not related to the Model, because if you will test with ADF BC Browser, it works well. Bug is related to View layer. This means we can invoke exposed method in View object and set Null value for LOV attribute programmatically. To achieve this, I have created my custom method in View object class and exposed this method through Client Row interface:

Exposed custom method clearLOV(), basically invokes setter method for DepartmentId attribute and provides Null.

In View layer, for my LOV component, I have set AutoSubmit=true property and provided ValueChangeListener in order to check when user will try to provide Null value:

ValueChangeListener compares new LOV value to Null, and if user is trying to set Null, exposed custom method is invoked trough bindings to set Null value programmatically:

And how it works? Let me at first to show how it works without workaround. Here we have a form with LOV component, by default value is not set for LOV:

Let's set provide any non Null value:

And now, when LOV value is stored in database, let's try to clear it:

Press Save button to store our last change and you will get previous value back - Null (or empty) value is not accepted anymore:

However, if you will use described workaround, Null value will be set as expected:

Wednesday, November 19, 2008

Hints for ADF 11g Application Credential and Policy Migration to Standalone WebLogic Servers

Recently I was deploying our ADF 11g application on standalone WebLogic server. Deployment itself is straightforward, however it is little bit more complex with security metadata migration from development environment to test environment. I have migrated application credentials and policy data using steps described in Steve Muench document - Simplified ADF 11g Application Credential and Policy Migration to Standalone WebLogic Servers. This document is very clear and useful, I would recommend to read and use for everyone who will face problem with security metadata migration to standalone WebLogic.

So, after you will read Steve's document, probably you will find those my 2 hints useful as well:

1) Even if you are not using ADF Security in your application, still in the most of the cases you will need to migrate application credentials. You will need to do this, if you are using JDBC URL as Connection Type to database, since database connection credentials are stored in credentials file. There is no need to migrate application credentials if you are using JDBC DataSource instead of JDBC URL. If credentials for JDBC URL Connection Type will not be migrated, most probably you will get similar error on runtime - Incomplete connection information:

2) After you will succeed to migrate application credentials and policy to the test environment, this doesn't mean you will be able to run your application immediately (in a case of DD Only Security Model). Its because system-jazn-data.xml available on standalone WebLogic is populated with users and policies from development environment, however those users are not mirrored to standalone WebLogic. This means, authentication step will not be completed.

In order to solve this issue, you can go to WebLogic console and in Security Realms (myrealm by default) you can define users you want to authenticate. There is no need to define roles for those users, since authorization will be done based on policies stored in system-jazn-data.xml available on standalone WebLogic after migration.

Saturday, November 8, 2008

ADF Query Component and View Criteria Functionality with Custom Query Listener in 11g

Nice new component in ADF 11g is ADF Query - af:query. This component allows to implement Search functionality in your applications with much smaller effort comparing to Search functionality implementation in 10g. In conjunction with View Criteria, ADF Query provides declarative way for Query Criteria forms development. There is no need anymore to have transient attributes for Query Criteria, since we can base it on View Criteria attributes from View object. In this post I will describe how you can implement user-friendly Search functionality in 11g and how to use custom QueryListener for ADF Query.

You can download developed application - This application provides sample page with ADF Query component and results table. Additionally, this application contains custom behavior - when there are pending changes in results table, re-query is not performed and user is forced to commit or rollback existing pending changes.

Good news about ADF Query - it can use List Of Values defined in Model layer. So, if we have List Of Values declared for DepartmentId attribute:

DepartmentId in ADF Query automatically will appear as List Of Values, since this attribute is declared in View Criteria on View object:

Sample page contains two main components - af:query and af:table with ID = resTab. First component implements ADF Query and second - table for results:

If you will select af:query component in Structure view, Property Inspector will show you all properties of af:query. You should pay attention to ResultComponentId property, its Id that points to component where Search results will be shown. Most important thing in my sample application - custom QueryListener processQuery(). I have created it custom, because I want to control query execution and not to execute query when there are pending changes in results table:

However, custom QueryListener declaration is not enough in order to control query execution regarding pending changes. Additionally, you need to set PartialTrigger on results table and point to ADF Query. This is needed in order to auto submit results table and inform Application Module about pending changes before executing query:

Created custom QueryListener is simple - if there are pending changed, query is not invoked, if there is no - standard QueryListener is invoked. Information about pending changes is retrieved from Application Module, using isDirty() function:

On runtime, you will see such screen - Query Criteria area and results table:

DepartmentId List Of Values is shown, you can use it to provide search criteria parameter:

Results table is populated and if user will decide to change for example HireDate column value:

And re-execute query with new query criteria for DepartmentId:

There will be pending changes message shown, since user didnt saved his/her last changes before re-executing query. When user will save pending changes and will query again, it will be successful: