Monday, January 28, 2008

Athens - Warm and Friendly City

I'm doing some traveling during those weeks. Last week I was in US, Connecticut. This week I'm in Greece capital - Athens. Local people say that it is winter here, but for me it seems like nice Spring :-)

And there are a lot of trees with yellow fruits. Looks like Orange tree? I got advice, that it's better not to try it, because it some kind of wild Orange and not tasty one :-)

Thursday, January 24, 2008

Using af:popup Component in JDeveloper 11g

This component is available in JDeveloper 11g ADF Faces Rich Client, I personally like how it works and how it looks. In this post I will show a use case where this component can be applied.

You can download developed sample application - This application is based on standard HR schema from Oracle XE database. However, I have extended this schema a little bit, by adding new column to EMPLOYEES table. New column is called ACTION_COMMENT and is used to implement defined use case. You can find SQL script needed to create this column in lt.andrejusb.model.sql.actioncomment file.

Ok, what is a use case implemented in this sample about? Main idea is - when user changes some information in the form and press button Save, pop-up is displayed with a field where user can enter comment for his action. If user don't want to provide any comment, just empty field can be submitted.

How it's done? Actually, pop-up functionality is created in two steps:

1. Put af:showPopupBehavior component on Save button in your form. This component is used to invoke pop-up when Save button is pressed:

You must assign PopupId and Align properties for af:showPopupBehaviour component:

2. Put af:popup component just right before Save button, actually there is no difference where to put it. You can use inside af:popu those components - Dialog, Menu, Panel Group Layout and Panel Window. I'm using in this sample Dialog component with Save button that invokes Commit functionality:

Important - af:popup should have the same Id value as af:showPopupBehavior component, this will allow to open pop-up when Save button is pressed:

Value for Action comment component is binded to #{processScope.actionComment}, when Save button is pressed entered value is stored into #{bindings.ActionComment.inputValue}. And finally, when Commit action is done, I'm clearing value stored in #{processScope.actionComment}:

So, two steps are described.

And it looks really nice in practice, let's say we have a form and modify some data:

When Save button is pressed - we have pop-up displayed. User can provide text to describe his action and submit data with Save button:

If user don't want to provide any text to comment his action, simply Save button can be pressed and form data will be saved.

Tuesday, January 22, 2008

Trip to US

I'm in US this week, Connecticut. Here is the same weather as in Lithuania, it's winter with about -5 degrees in Celsius.

Wednesday, January 16, 2008

Oracle to acquire BEA

Hey, great news !

Oracle announced today that they are going to acquire BEA Systems. From Oracle Press Release:

Oracle Corporation (NASDAQ: ORCL) and BEA Systems (NASDAQ: BEAS) announced today they have entered into a definitive agreement under which Oracle will acquire all outstanding shares of BEA for $19.375 per share in cash. The offer is valued at approximately $8.5 billion, or $7.2 billion net of BEA's cash on hand of $1.3 billion.

Oracle CEO Larry Ellison said:

"The addition of BEA products and technology will significantly enhance and extend Oracle's Fusion middleware software suite".

Tuesday, January 15, 2008

ODTUG Kaleidoscope '08 - Abstract Accepted

Good news from me - my submitted abstract for ODTUG Kaleidoscope '08 conference is accepted :-)

Presentation title is - Development with Oracle JDeveloper/ADF 11g Reusing 10g Best Practices.

What about it will be? Presentation will be done in interactive way, like I did during Oracle OpenWorld Unconference in San Francisco - Oracle JDeveloper/ADF Real Life Story. I will show how knowledge acquired during development with Oracle JDeveloper/ADF 10g, can be applied when working with new Oracle JDeveloper and ADF release - 11g.

See you in New Orlean during June 15 - 19.

Complex Calculated Values in Oracle ADF af:table Component

Title of this post not accidentally contains word 'complex', developed sample application is really a bit complex, but I will try to describe it in easy way. Some time ago I was blogging about how to include calculated column into af:table component - Calculated Column in ADF Faces af:table Component. But, it was just separate read-only calculated column based on values available in other columns. However, what if you need to include calculation logic for database table related column and on the same time allow it to be editable.

Developed sample application - is based on HR schema available in Oracle XE database and implements logic that allows to edit two calculated columns - MinSalary and MaxSalary.

Calculation rule applied for MinSalary:
  • IF (MaxEmployeeSalary - AvgEmployeeSalary <>
Calculation rule applied for MaxSalary:
  • IF (AvgEmployeeSalary + MaxEmployeeSalary > MaxSalary) THEN update(MaxSalary)
If described conditions will not be satisfied, this means value that was entered by user will be stored in database.

MaxEmployeeSalary and AvgEmployeeSalary are values calculated in EmployeesQueryView:

Calculations for both columns are done in Backing bean, methods are invoked through dummy binding to ReadOnly property:

All calculations related to MinSalary are done in getCalculatedMinSalary() method. Based on JobId parameter are calculated AvgEmployeeSalary and MaxEmployeeSalary values, and if specified condition is satisfied MinSalary is updated:

MaxSalary is calculated in exactly the same way as MinSalary.

Now I will show how it works. Let's say we want to focus on PU_CLERK salary:

If in Employees table we set Salary values for PU_CLERK to 1900, 1600, 1700, 1600, 1500 and press Save button - MinSalary in Jobs table for PU_CLERK is updated to 240:

MaxSalary is not updated, because AvgEmployeeSalary + MaxEmployeeSalary = 3560 and this is less comparing to current 8000. So, user can set MaxSalary manually to let's say 5000 and this value will be stored in database:

When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.

Sunday, January 6, 2008

Hints for List-Of-Values (LOV) in JDeveloper 11g TP3

Recently I was experimenting with LOV component provided by JDeveloper 11g Technology Preview 3. What I can say - if you are planning to use this component with current JDeveloper 11g TP3, you definitely will face some issues. However, in this post I will describe two workarounds I found, hopefully this will be helpful until next JDeveloper 11g Technology Preview will be released.

Sample application - is based on two problems and implements workarounds I have described in OTN forum. I will describe those two problems and workarounds I found.

1. LOV with Read-Only View object (Server Exception during PPR, #1)

First problem I faced was Server Exception during PPR error. This exception was generated right after some value in LOV was selected and OK button was pressed. So, in other words LOV wasn't working:

LOV component was based on Read-Only View object, I have created this View object separately - with New View Object... wizard.

However, when I have tested Model layer with Oracle Business Components Browser everything was working fine. So, LOV wasn't working in ADF Faces Rich Client, but was working when testing Model layer. I decided to create new Read-Only View object with Business Components from Tables wizard and to test it with LOV component - it was working. I have compared two Read-Only View objects and noticed that there was only one difference - Key Attribute wasn't set for View object generated with New View Object... wizard:

I have set Key Attribute in JobsLovView, and LOV started to work as it should work. But, I have faced other issue - incorrect behavior in Create form.

2. LOV issue in Create form with Mandatory fields

Let's say we have Create form, all fields in Create form are empty and some fields are indicated as mandatory ones:

Everything seems clear and correct, but when user will try to set value from LOV component - validation errors will be generated. Validation errors for all empty mandatory fields, you should agree this is quite strange behavior - it's impossible to use LOV component until other mandatory fields are empty. LOV component is opened, but when value is selected and submit button is pressed, similar screen is shown:

Problem is described, but how to solve it? One solution is to wait for next JDeveloper 11g Technology Preview release, other solution is to find workaround. My suggested workaround is to remove standard ADF Business Components validation for mandatory fields and implement custom validation. Also, its even possible not to implement custom validation in ADF, in this case validation will be done on database side.

In this post I will describe how to implement custom validation in ADF. First, deselect all Mandatory fields, available in Create form where LOV components are used:

In Create form, set for all mandatory fields, ShowRequired property to true. This will inform user about required fields in the form:

Custom validation will be done, when user will try to submit form data into database. So, we can create Action method for Save button and check all required values there:

Custom validation code in saveButton_action() method is straightforward:

Sample application implements both described workarounds. Value in LOV component can be successfully selected and returned into Create form:

Value in LOV component is selected and data in other fields is provided also, data in Create form is ready to be submitted into database:

We can test, how implemented custom validation works. Let's say value in Email field is removed and Save button is pressed - validation logic in Backing bean catches this and prints error message:

Tuesday, January 1, 2008

Complex List-Of-Values (LOV) in Oracle ADF

My first post in 2008 :-)

Today I will explain how to develop LOV component with three dependent tables and to return a set of values from LOV to parent table. Sample application - is based on HR schema, you can find it in Oracle XE database. However, custom VACATIONREQUESTS table is used as well, it is used to implement three dependent columns. You can find information about this table and needed scripts in my previous post - Three Dependent List Boxes in af:table Component.

The main problem I'm describing in this post is about how to return several values from LOV component and update parent table with selected values from backing bean.

In Model layer I have generated four Entity objects - Department, Employees, Locations and Vacationrequests. Four View objects are generated as well. In HrModule I have enabled dependency between three View objects by adding EmployeesView4 instance into DepartmentsView3 instance.

In View layer I have created two pages - main and lov. First page contains three dependent columns, values in those columns can be changed using LOV component. Second page provides LOV component - three dependent tables. Page flow for developed sample application:

Now I will describe in three steps, how LOV with three dependent tables works, how values from LOV are returned and how parent table is refreshed.

1. LOV - three dependent tables

Dependent tables I have created by generating Master Table - Detail Table components from Data Control. I have generated two such components. However, in second component I removed Master table and have wired Detail table Employees to Departments table from first Master Table - Detail Table component. I have wired it by setting AutoSubmit=true for af:tableSelectOne component in Departments table and by setting PartialTriggers=departments on Employees table.

2. LOV - Set button

Set button in LOV window have setButton_action() method binded. Also this button contains af:returnActionListener component, this component is used to close LOV window when Set button is pressed. Let's concentrate on setButton_action() method:

This method is invoked when Set button is pressed. Iterators of all three dependent tables are accessed here and Id's are retrieved. Retrieved Id's are stored in valueHolder managed bean.

3. Parent table - refreshOnReturn()

When values in LOV are selected and and LOV is closed, ReturnListener associated with LOV button in parent table is invoked. refreshOnReturn() method retrieves returned values stored in managed bean and sets those values for current row in table:

When new values are set - refreshCurrentPage() method is invoked, this method executes refresh for current page. To make it work, don't forget to put PartialSubmit=true on button that invokes LOV component.

All steps are described, now I will show how it works. Table contains three dependent columns - LocationId, DepartmentId and EmployeeId. Values for those columns are set using LOV component. Table:

We can select any row in this table we want to update and press LOV button - LOV component will be opened:

You can notice values I have selected in LOV - 1700, 30, 117. When Set button is pressed - row in parent table is updated with selected values:

When running sample application, don't forget to add adf-faces-impl.jar and jsf-impl.jar to application's WEB-INF\lib directory.