While doing Oracle ADF 11g training during this week, we were discussing with students about Optimistic and Pessimistic locking support in ADF BC. Actually, while available documentation gives you good insight into theoretical side of locking mechanism, its still quite hard to understand how it really works and when we should apply Optimistic or Pessimistic locking. I have prepared sample application, where I'm describing differences between those two.
Download - OptimisticPessimisticLocking.zip application, it is configured by me to work in Optimistic locking mode. Let's switch to Pessimistic locking (default one), you can do this through ADF BC application module settings:
In order to test locking behavior, we need to simulate multiple users - just open sample application with two separate browsers:
We change data in the second browser (second user), press Save button. Then we go to the first browser (first user), modify data and press Save - error about concurrent data modification in current will be shown:
And now is very important part - let's assume that user in the first browser will wait and will not try to save or undo his changes. This basically means, in Pessimistic locking case, database lock from the first user still will remain in database. Now, if second user will go to modify same record and will try to save it:
The second user will get error about database lock - user will be stuck in current record:
The second user will be forced to wait until first user will Save or Undo his changes in order to proceed with data commit. Another option for the second user - Undo his change in the current row and proceed with other rows editing. When the first user will close his transaction, the second one will be able to save his changes for previously locked record as well:
Now we will see how it works in Optimistic mode:
The second user is changing data, committing it and then first user is doing change in the same row and trying to save it - error about concurrent modification will be generated:
However in Optimistic locking case, the first user will not hold database lock and second user will be able to continue his work (with the same or other records):
At the same time, first user will be able to press Save button second time, and his data will be committed.
Sunday, March 28, 2010
Friday, March 19, 2010
Passing Parameters from ADF Task Flow with Fragments into ADF Bounded Task Flow
It is a common use case to pass parameters from ADF Task Flow with fragments into another ADF Task Flow without fragments. I got this question for my previous blog post - Parent Action Activity in ADF Task Flow. The use case:
1. We have ADF Bounded Task Flow, it contains two main elements - page P1 and another ADF Task Flow call - C1
2. Page P1 included ADF region, this region comes from ADF Task Flow with Fragments
3. We need to pass parameter from ADF region available in P1 into ADF Task Flow call C1
How this can be achieved? If the bounded task flows referenced by ADF regions share the data control scope and the transaction - we can access parameter directly through Expression Language. If data control scope is not shared - probably you will need to use ADF Contextual Event Framework. Today I will describe first case, and will go through ADF Contextual Event Framework in my next posts.
Download sample application - ADFRegionNavigation2.zip. This sample is based on application from my blog post mentioned above and implements ADF Bounded Task Flow with input parameter:
I want to pass value from ADF region into this parameter. When the data control scope is shared, it is enough just to reference Attribute Value available in ADF region Page Definition:
Make sure you understood, why data prefix is used, instead of bindings as usual. It is because in this case, we are accessing Page Definition element directly from ADF Task Flow. You can construct Expression Language statement with Expression Builder wizard:
Thats it - parameter from ADF region will passed now to ADF Bounded Task Flow. If we select some country from table component available in ADF region:
And press Locations button - Parent Activity will be triggered and we will navigate into ADF Bounded Task Flow, where parameter value from ADF region will be successfully passed and displayed:
1. We have ADF Bounded Task Flow, it contains two main elements - page P1 and another ADF Task Flow call - C1
2. Page P1 included ADF region, this region comes from ADF Task Flow with Fragments
3. We need to pass parameter from ADF region available in P1 into ADF Task Flow call C1
How this can be achieved? If the bounded task flows referenced by ADF regions share the data control scope and the transaction - we can access parameter directly through Expression Language. If data control scope is not shared - probably you will need to use ADF Contextual Event Framework. Today I will describe first case, and will go through ADF Contextual Event Framework in my next posts.
Download sample application - ADFRegionNavigation2.zip. This sample is based on application from my blog post mentioned above and implements ADF Bounded Task Flow with input parameter:
I want to pass value from ADF region into this parameter. When the data control scope is shared, it is enough just to reference Attribute Value available in ADF region Page Definition:
Make sure you understood, why data prefix is used, instead of bindings as usual. It is because in this case, we are accessing Page Definition element directly from ADF Task Flow. You can construct Expression Language statement with Expression Builder wizard:
Thats it - parameter from ADF region will passed now to ADF Bounded Task Flow. If we select some country from table component available in ADF region:
And press Locations button - Parent Activity will be triggered and we will navigate into ADF Bounded Task Flow, where parameter value from ADF region will be successfully passed and displayed:
Thursday, March 18, 2010
Grant Ronald Explains Oracle ADF/JDeveloper/Fusion in Czech Republic
For those of you who live in Czech Republic, and who are planning to use or already using Oracle Fusion technology, I recommend to attend Grant Ronald training. He will be in Czech Republic soon - check his blog post for more info.
Well, what I can say - years ago, I have started to learn ADF from Grant training materials.
Well, what I can say - years ago, I have started to learn ADF from Grant training materials.
Saturday, March 13, 2010
Applying View Criteria from Application Module
Often we need to define and invoke View Object filtering. In ADF 11g we can do this by adding WHERE clause to View Object SQL statement or by defining View Criteria and invoking it later. I prefer second approach, why I should play with SQL statement, if ADF 11g can generate it for me. Okej, when there is View Criteria, it should be invoked. There are different approaches to do this - from declarative to programmatic. Today I will describe my preferred approach, I'm not saying you should use it as well.
Download sample application - AppModuleQuery.zip. This sample implements View Criteria to filter employees based on their department:
Here is the first trick - I have defined Bind Variable setter method to pass variable value and exposed this method through client interface:
This means I will call it later from Controller layer to pass correct Bind Variable value. Its important to say, you should do ExecuteQuery when new Bind Variable is passed, this will ensure it will be correctly reinitialized:
Now most interesting part starts, you can declare View Criteria to be executed automatically, each time when View Object is accessed. You can do this in Application Module - select View Object from Data Model section and click Edit:
Select View Criteria you want to trigger automatically - it will be invoked each time when View Object will be accessed:
Model part is done, now its time to look into Contoller. As you remember, Bind Variable setter method was exposed through client interface, it is present in Data Control:
Drag and drop it into ADF Bounded Task Flow, it is needed to set correct Bind Variable value. In my case it is defined as Default Activity:
On runtime, JobId value is passed as Input Parameter for ADF Bounded Task Flow, where it is used for Bind Variable setter method parameter:
ADF Bounded Task Flow is opened, Bind Variable value is set and View Criteria applied automatically:
Download sample application - AppModuleQuery.zip. This sample implements View Criteria to filter employees based on their department:
Here is the first trick - I have defined Bind Variable setter method to pass variable value and exposed this method through client interface:
This means I will call it later from Controller layer to pass correct Bind Variable value. Its important to say, you should do ExecuteQuery when new Bind Variable is passed, this will ensure it will be correctly reinitialized:
Now most interesting part starts, you can declare View Criteria to be executed automatically, each time when View Object is accessed. You can do this in Application Module - select View Object from Data Model section and click Edit:
Select View Criteria you want to trigger automatically - it will be invoked each time when View Object will be accessed:
Model part is done, now its time to look into Contoller. As you remember, Bind Variable setter method was exposed through client interface, it is present in Data Control:
Drag and drop it into ADF Bounded Task Flow, it is needed to set correct Bind Variable value. In my case it is defined as Default Activity:
On runtime, JobId value is passed as Input Parameter for ADF Bounded Task Flow, where it is used for Bind Variable setter method parameter:
ADF Bounded Task Flow is opened, Bind Variable value is set and View Criteria applied automatically:
Wednesday, March 10, 2010
A Reader Asks - How To Pass Table Export Id Into ADF 11g Declarative Component
"I'm trying to use ExportCollectionActionListener inside Declarative Component, but I can't pass table export Id correctly - it gives error, Id is not found. Is it possible to make it work?"
Yes, it is. Download sample application - DCLibExport.zip. This archive contains two JDeveloper 11g applications - Declarative Component (ExportToolbarLib) and consuming application (EmployeesExport). I will not talk about Declarative Components in this post, you can read more about them from previous post.
Declarative Component example is really simple, it contains one attribute - exportId. Such type of components are really useful for proper application design and architecture, it allows to achieve proper reusability - instead of declaring Export buttons for each table, we are doing it only once:
And one button with ExportCollectionActionListener assigned, this will allow to export table data to Excel format automatically:
Important thing to mention - ExportCollectionActionListener gets ExportedId property value from Declarative Component attribute:
This means, we will be able to provide table Id value directly from consuming page and reuse Declarative Component in many pages.
Consuming application declares Tag library for Declarative Component - ExportToolbar:
Library is available in Component Palette:
Consuming page structure defines three main elements: data table, panel collection and export toolbar (our Declarative Component):
Here is main question now - how to wire together Export listener from Declarative Component and table in consuming page. The main trick - we should declare complete path and pass it through ExportId attribute. We should specify ExportToolbar Id (et1), enter into this component, and reference Panel Collection (pc1) from there. Finally, we need to access table component (t1) itself. Expression language for this case: #{et1::pc1:t1}:
On runtime we can see Export button from Declarative Component and ADF table with data:
Export works successfully:
Yes, it is. Download sample application - DCLibExport.zip. This archive contains two JDeveloper 11g applications - Declarative Component (ExportToolbarLib) and consuming application (EmployeesExport). I will not talk about Declarative Components in this post, you can read more about them from previous post.
Declarative Component example is really simple, it contains one attribute - exportId. Such type of components are really useful for proper application design and architecture, it allows to achieve proper reusability - instead of declaring Export buttons for each table, we are doing it only once:
And one button with ExportCollectionActionListener assigned, this will allow to export table data to Excel format automatically:
Important thing to mention - ExportCollectionActionListener gets ExportedId property value from Declarative Component attribute:
This means, we will be able to provide table Id value directly from consuming page and reuse Declarative Component in many pages.
Consuming application declares Tag library for Declarative Component - ExportToolbar:
Library is available in Component Palette:
Consuming page structure defines three main elements: data table, panel collection and export toolbar (our Declarative Component):
Here is main question now - how to wire together Export listener from Declarative Component and table in consuming page. The main trick - we should declare complete path and pass it through ExportId attribute. We should specify ExportToolbar Id (et1), enter into this component, and reference Panel Collection (pc1) from there. Finally, we need to access table component (t1) itself. Expression language for this case: #{et1::pc1:t1}:
On runtime we can see Export button from Declarative Component and ADF table with data:
Export works successfully:
Tuesday, March 9, 2010
Integration in Oracle ADF with ADF Task Flows and Dynamic Regions Navigation
Today one more post from Integration series. There is a case, when Dynamic Region might have navigation to another Dynamic Region. If user will open one region from another, menu selection should be refreshed accordingly. I'm describing how to do this, thanks to blog Reader who asked this question.
Download updated sample - ADFIntegrationRegions3.zip, based on my previous post. Main change comparing to previous post sample - there is ADF Task Flow call from Locations to Departments:
All separate applications are deployed and assembled into one main application, same as it was described before. Only one difference now - first Dynamic Region (Locations) contains Departments buttons, it will navigate to second Dynamic Region (Departments) directly:
User can click on Departments button:
And here we go - Departments Dynamic Region is opened, menu item selection is synchronized as well:
Well, how to implement this? There is a very good hint in Frank Nimphius and Lynn Munsinger book (Building RIAs w/ Oracle ADF) on page #201 RegionNavigationListener. We can declare it for af:region:
And listen for navigation from Locations to Departments, if such navigation happens - we reset menu and switch Dynamic Region (Departments) as current:
Its how it works.
Download updated sample - ADFIntegrationRegions3.zip, based on my previous post. Main change comparing to previous post sample - there is ADF Task Flow call from Locations to Departments:
All separate applications are deployed and assembled into one main application, same as it was described before. Only one difference now - first Dynamic Region (Locations) contains Departments buttons, it will navigate to second Dynamic Region (Departments) directly:
User can click on Departments button:
And here we go - Departments Dynamic Region is opened, menu item selection is synchronized as well:
Well, how to implement this? There is a very good hint in Frank Nimphius and Lynn Munsinger book (Building RIAs w/ Oracle ADF) on page #201 RegionNavigationListener. We can declare it for af:region:
And listen for navigation from Locations to Departments, if such navigation happens - we reset menu and switch Dynamic Region (Departments) as current:
Its how it works.
Monday, March 8, 2010
Red Samurai Tool - How To Check ADF 11g Package Structure and ADF Task Flow Parameters
In my previous post, I have introduced our JDeveloper 11g extension for ADF code quality validation. I will describe two rules more and will show how you can scan your ADF project for standard guidelines violations. Package structure check and task flow input parameters are documented today.
I'm demonstrating rule execution using updated sample application - RedSamuraiToolTestSample1.zip. Just to remind you, extension can be invoked by right clicking on Model or ViewController project and selecting it from available menu:
I will choose to run Package Structure Check rule:
Several violations are reported for - Application Module, View Link and Association:
Let's double check Model project structure, and we can see that report was correct - we need to fix few things for application package structure:
First, I will refactor Application Module into appmodules package:
If we run same rule again, this time only two violations will be reported - good progress:
We need to complete the rest of refactoring for View Link and Association - whole picture is correct now:
This is confirmed by our extension as well - no more violations for package structure:
Different projects may have different package structure standards, you can customize Red Samurai extension execution through preferences window:
Another rule I will describe - ADF Task Flow parameters naming convention:
Let's assume, we have a standard to give in prefix for ADF Task Flows parameter names. Developer forgot this standard and gave incorrect name - myParameter:
We run our rule to scan for ADF Task Flow input parameters names:
And here we go - rule violation is reported:
When parameter name is fixed to be inLastName:
No more violations for this rule are reported:
I'm demonstrating rule execution using updated sample application - RedSamuraiToolTestSample1.zip. Just to remind you, extension can be invoked by right clicking on Model or ViewController project and selecting it from available menu:
I will choose to run Package Structure Check rule:
Several violations are reported for - Application Module, View Link and Association:
Let's double check Model project structure, and we can see that report was correct - we need to fix few things for application package structure:
First, I will refactor Application Module into appmodules package:
If we run same rule again, this time only two violations will be reported - good progress:
We need to complete the rest of refactoring for View Link and Association - whole picture is correct now:
This is confirmed by our extension as well - no more violations for package structure:
Different projects may have different package structure standards, you can customize Red Samurai extension execution through preferences window:
Another rule I will describe - ADF Task Flow parameters naming convention:
Let's assume, we have a standard to give in prefix for ADF Task Flows parameter names. Developer forgot this standard and gave incorrect name - myParameter:
We run our rule to scan for ADF Task Flow input parameters names:
And here we go - rule violation is reported:
When parameter name is fixed to be inLastName:
No more violations for this rule are reported: