Tuesday, February 25, 2014

Red Samurai Performance Audit Tool v 2.8 - Activation Focus

Here we come again - new minor update for Red Samurai Performance Audit Tool is prepared in our labs. Update 2.8 is focused on more accurate ADF BC activation time tracking. As you may already know, from my previous blog post - ADF BC Performance - View Object Instance Lazy Activation, ADF BC may apply deferred activation for VO instance. If instance is not used in the current Page Definition, this instance will be activated later, when user opens a page or fragment with such VO instance. For more technical details and sample application, please read my blog post mentioned above. We are keeping this behaviour in mind, when logging slow activations, this allows to understand real impact of slow activations and display it in the audit reports.

Drill down graph for slow activations analysis is updated with search functionality, you can browse through activations using different search criterias (such as time, data, VO's involved, etc.):

I'm filtering here all slow activations reported by date. I can see there are many slow activations reported with time close to 0 - 30 seconds. I could restrict my search criteria by filtering activation time in the interval of 0 - 30 seconds:

It is much easier now to analyse and drill down into group of slow activations.

The size of the point reflects number of VO instances involved into activation group. 33 VO instances are involved in this specific case, other details as time, records fetched, etc. are displayed as well:

We have planned several new exciting updates in the future. Read here about features included in previous update - Update for Red Samurai Performance Audit Tool - v 2.4.

Thursday, February 20, 2014

ADF BC Performance - View Object Instance Lazy Activation

ADF BC is a great framework to manage data, but one thing it does really smart - ADF BC View Object instance lazy activation. You must know by now - passivation/activation events in ADF BC are relatively expensive in terms of performance. Especially expensive is activation event, as during this event View Object instance is re-constructed and data is re-fetched. However, it is not as bad as it sounds - it doesn't activate all View Object instances from Application Module together. Only View Object instances referenced from current Page Definition are activated. This means, if user was working with 10 screens, before passivation event happened - during activation event, only View Object instances from current screen will be activated. View Object instances from other screens will be activated, when actual screen will be accessed. Good news - you don't need to tune anything for this, this is how it works by default.

We track ADF BC performance with Red Samurai Performance Audit Tool - Update for Red Samurai Performance Audit Tool - v 2.4. Slow activations are recorded as well, this allows to measure activation event impact to your ADF application performance.

To prove lazy View Object instance activation scenario, I have developed sample application - AMStatisticsApp_v2.zip. Application Module is set to support only one referenced instance, this means we can force passivation/activation events with two Web sessions running in parallel:

AM data model contains two different View Object instances, this is to check if both will be activated on the same time:

Generic VO implementation class overrides activateCurrentRow method, to record activation event for View Object instance. Red Samurai Performance Audit Tool overrides the same method, to log slow activation, as this method is called at the end of activation event - when all records for the VO rowset were fetched:

On Task Flow side, I have created two fragments (each for VO instance from AM data model):

Each fragment is mapped with its own Page Definition file, this means each fragment have its own bindings:

To test provided sample application, make sure to set FINEST logging level for Generic VO implementation class:

Open application, first fragment with Employees data will be loaded:

Go to Departments fragment, to load Departments VO instance and navigate back to Employees:

Open second browser session, without closing the first one:

Referenced Pool Size is set to 1, this means AM instance from first session will be passivated. Now go back to the first session browser and change row selection - you will see in the log activation event for the Employees VO instance only:

Departments VO instance was not activated yet, as it belong to different Page Definition, it will be activated lazily - when data from second Page Definition will be loaded. Navigate to the Departments fragment, mapped with the second Page Definition:

Only when you navigate to Departments, and load data from Departments Page Definition - it activates Departments View Object instance - see new message printed in the log. This is quite smart and good functionality in terms of activation performance:

Monday, February 17, 2014

Simple JQuery Notification Message for ADF UI

If you would like to use JQuery in ADF and looking for some simple example, this post if for you. I'm sharing use case of JQuery notification message, displayed after successful commit operation is completed in ADF. Once commit is completed, notification message is displayed for 2 seconds and later it disappears.

Here you can see, how it looks. User successfully saved changed data - notification message is displayed about success - it nicely slides from the top. Message is displayed nicely on top of ADF UI, ADF UI components aren't pushed down:

In a case of failure during commit, for example if validation rule fails or DB constraint prevents data update, no notification about success is displayed - but only standard ADF error message:

JQuery notification message code is taken from the referenced source, we just updated it for better integration with ADF Faces, you can see entire code in the sample application - ADFNotification.zip:

JQuery Java Script library is integrated into ADF application fragment through ADF Faces resource component, just as any other Java Script code:

Notification message is displayed from ADF managed bean, action method. Firstly ADF commit operation is executed, if it returns error - no notification is displayed. Code to display notification message could be generic, as a part of your core framework structure:

I hope this simple example, would help to create even nicer UI's for CRUD applications, implemented with ADF.

Wednesday, February 12, 2014

Collecting Changed Row Keys in ADF BC DoDML Method

If you ever had a question - how to collect information about all changed rows in the transaction, I will provide an answer in this post. As you perhaps already know, doDML method from Entity Implementation class is invoked per each changed row. This means our task is to collect Primary Keys for all changed rows and later access this collection from another method, to be able to process collected keys (log them, call PL/SQL, etc.).

Sample application - DoDMLExceptionProcessingApp_v2.zip, overrides doDML method and collects all changed rows for Employees EO. In real use case, this should be more generic, if you want to apply similar logic for different EO's, however you should follow the same concept as described here. In doDML I collect information about Primary Key programmatically, getting key value and saving it in collection. Later this collection is stored in ADF BC session user data. There is no need to passivate collection with changed rows Primary Keys, as we are going to access it in the same request from afterCommit method on VO level - there will be no passivation in between:

I'm using a trick to get information about Entity primary key programmatically. There is a method called getPrimaryKeys in Entity Definition class, but this method is marked as protected, so I can't access it from custom code. However, I can implement my own Entity Definition class, override getPrimaryKeys protected method inside custom public method - in such way, I will make it available for custom methods:

doDML is invoked for every changed row, we need a method to be called at the end, to access collected info. Such method could be - afterCommit in View Object Implementation. This method is called after all rows are processed in doDML. I'm getting information about Primary Key and accessing ADF BC user data variable, where Primary Keys for all changed rows are stored. In this example, I'm simply printing out keys for all changed rows:

Here we can see, how it works. Change data in multiple rows and press Save:

Information about Primary Key name and values for every row containing changes is printed out:

We could use Primary Key values to access changed rows, process attributes we are interested in and call PL/SQL if required, using attribute values as parameters.

Friday, February 7, 2014

Explaining Change Indicator Property for ADF BC Attribute

There is one not very visible, but quite powerful property available for ADF BC Entity Object attribute. This property is called - Changed Indicator. By default, during commit operation, ADF scans each changed attribute from the current row and compares value in the DB. If it locates changed values in DB, reports error about another user changes in the same row. While this is expected functionality, there are use case when we want to allow commit, even data was changed already by someone else. For example, in more complex systems, data is updated by PL/SQL procedures, we don't want to inform user with error about this. There is a way to override lock method in EO implementation class, catch lock error and raise lock again. This works, but there is different way - to use Change Indicator. This property defines specific attribute to be responsible for row data changes tracking, instead of checking every attribute. Only if Change Indicator attribute value will be changed in DB, then current row changes will be prevented and user will be informed about someone else changes in the same row.

My previous post - Different Approach for DB Constraint Error Handling in ADF, about handling DB constraint errors is using Change Indicator defined for Primary Key. In this way, I'm completely ignoring changes by other users and allowing to commit data no matter if it was changed by someone else.

Here you can download sample application with Change Indicator demo - ChangeIndicatorApp.zip. Change Indicator can be set on EO attribute, I'm using Department Id in this example. This would mean, all changes are allowed without informing a user about new changes in DB, except when Department Id is changed:

I'm running sample application with two different sessions. Changing Salary value in both sessions, for the same row. Salary is changed in the first session, but not yet committed:

The same row Salary is changed from the second session and committed with Save button:

Committing from the first session, data in the same row, doesn't bring error about data changed by another user. As expected, since Change Indicator value was not changed - ADF doesn't know about changes in the DB:

If I would invoke rollback in the second session now, by pressing Cancel button - I can see that the last updated Salary attribute value is displayed:

We can simulate data change in the DB and trigger update in Change Indicator. Let's update Change Indicator column value and commit this change:

Go back to the ADF UI, change data in the same row and try to save it:

Change Indicator value was changed, we are going to get error about another user changes in the same row - as expected this time. Notice that Change Indicator value is updated, Department Id is set to 30:

As it works by default in this case, press Save button second time, data will be saved for the new Department Id:

Wednesday, February 5, 2014

Different Approach for DB Constraint Error Handling in ADF

Let's be honest - no matter how developer friendly and stable validation rules support would be in ADF BC, there will be always use cases when validation logic will be executed directly in DB, by check constraints for example. There is one problem in ADF, when validation logic is executed by DB check constraints. As there will be error received in doDML, while posting row and violating check constraint - transaction will stop and no other edited rows will be verified, until currently failed row data will be fixed. I will explain in this post, how to bypass such behaviour and have to report failed rows to ADF UI.

Key part to understand - there are two transient attributes defined on VO level. These two should be defined on VO level, if you would define them on EO level, transient attributes from EO level would not be included into passivation and values would be lost. One attribute is used as a flag to indicate DB constraint error for current row and other attribute keeps error text:

Both attributes are set to be included into passivation cycle. This would not be possible for transient attributes defined on EO level:

Method doDML is overriden on EO level to catch error from DB check constraint. In this example, I'm processing only Salary > 0 DB check constraint. In case of error from DB, error text is saved into ErrorText transient attribute from current row. ErrorIndicator is set to be 1, if error happened, and 0 otherwise. I'm getting current VO row for the current EO, by accessing it from root AM:

On UI side, we add Partial Trigger to the surrounding Panel Collection from Save/Cancel buttons. This will ensure error code and error text for the affected rows will be updated:

There are client and server listeners defined for the table to enable row double click support, this is how error message will be displayed to the user (instead of annoying popup showing up constantly):

Error message from currently selected row is retrieved and displayed through Faces message. I'm checking if error exists for the current row and only then display it - quite straightforward:

Here is example, where user was trying to submit changes in three rows, all set with negative salary. Of course DB check constraint for positive salary failed and we can see failed rows highlighted in red. You can double click on row highlighted in red and then error text popup will be displayed:

Let's fix salary in the second failed row to be positive and press Save again. Two rows will remain in failed state, but data from the fixed row will be saved to DB successfully:

We can double click on the first failed row to see the error message:

Fix salary to be positive in the first row and commit again - only one row with error will remain in pending state:

Download sample application - DoDMLExceptionProcessingApp.zip.