Skip to main content
This revision made June 08, 2012 12:11, by steven.davelaar

ADF Samples - ADF Business Components

Activation/Passivation

SMU161 Signal RowInconsistentException Correctly Across Activation/Passivation [11.1.1.5] 02-NOV-2011
This example illustrates an approach to ensure that the RowInconsisentException is correctly signalled even if the AM used by the second user has undergone passivation and activation since the first user changed the row. First, it's important to understand the potential problem. Assume that two users U1 and U2 query up the DEPT row with DEPTNO=10. User U1 modifies the Dname in that row and commits. At this point user U2 is looking at a "stale" value in the page in her browser. User U2 proceeds to make her edit and clicks (Commit). In an ADF page implemented in the typical way, the user will correctly get a warning that "Another user has changed the row" as long as U2's application module has not undergone passivation and activation. If instead application load forces ADF to activate the AM's passivated state to service user U2's (Commit)-button click request, then the change made by user U2 is silently committed, potentially overwriting the changes that user U1. This occurs because the act of activating the AM state reads in current DB values of the queried rows, which now reflect the changes made by user U1 instead of the values that are in user U2's current browser page. The solution involves using a change indicator attribute and including that change indicator attribute in the web page as a hidden field. In the example, the Dept entity object is based on the DEPT_WITH_OBJ_VERSION table. This is the standard DEPT table to which has been added a single, additional NUMBER column named OBJECT_VERSION. The ObjectVersion attribute in the Dept entity is marked as a 'Change Indicator' attribute, and it's also marked as a 'History Column' of type 'version number'. The history column setting tells ADF to automatically set the value of this column to 1 in a newly created row, and to increment the version number each time the row is modified and saved. The change indicator setting tells ADF to compare only the value of this attribute in order to determine whether the row has been changed by another user or not. In the absence of a change indicator attribute, ADF must compare the values of all persistent attributes which can take longer. The view1.jspx page uses the h:inputHidden component to include the ObjectVersion attribute value in the page. By doing this, the object version of the row being edited by user U2 will be submitted to the server along with the other attribute values, and it will be used to compare against the ObjectVersion attribute value of the row being edited. Since these values differ, the RowInconsistentException is thrown as desired. Try re-enabling the AM Pooling to convince yourself that the technique will work under normal circumstances as well. To run the example, start by running the CreateTables.sql script to create the DEPT_WITH_OBJ_VERSION table. Then run the view1.jspx page. Once the page appears in your default browser, copy the URL http://localh­ost:7101/Signa­lRowInconsiste­nt/faces/view1 and paste it into a different browser. For example, if Google Chrome is your default browser, paste it into Firefox or Internet Explorer. This will allow you to test having two distinct browser users using your application. Both browsers should be looking at the row for DEPTNO=10. In the first browser window, update the value of Dname and click (Commit). Now the second browser is looking at a "stale" value for the Dname. In this second browser, update the value of Loc and click (Commit). The user gets the expected error "Another user has changed the row with primary key oracle.jbo.Key[10]". The AppModule application module in the example has its 'Enable Application Module Pooling' configuration setting (jbo.ampool.doampooling) set to false for testing purposes. Your application module will never have this pooling setting disabled in production, but it is useful for testing the activation-safety of your application module by stress-testing the passivation/activation on each HTTP request.

See also Steve Muench' undocumented 10.1.3.x samples nr. 115

Bind Variables

SMU154, SMU126, SMU118

Calling PL/SQL in Database

See also Steve Muench' undocumented 10.1.3.x samples nr. 100

Control Hints

SMU137

Customizations/Extensions

SMU131

Declarative VO's

SMU141

Dynamic JDBC Credentials

SMU129

Groovy

SMU149, SMU143

Oracle Sequence

SMU109

Programmatic Business Components

SMU147, SMU133, SMU132, SMU111

Transaction Handling

SMU127

Validation

SMU159, SMU155, SMU153, SMU123, SMU105, SMU102

Difference compared to previous revision

ADF Samples - ADF Business Components

__TOC__ ===Activation/Passivation=== {| border="1" |- | "/>[[#SMU161|SMU161]] | [http://java.net/projects/smuenchadf/sources/samples/content/SignalRowModifiedByAnotherUserExceptionEvenWhenAMPoolingDisabled.zip Signal RowInconsistentException Correctly Across Activation/Passivation] [11.1.1.5] 02-NOV-2011 |- ||| This example illustrates an approach to ensure that the RowInconsisentException is correctly signalled even if the AM used by the second user has undergone passivation and activation since the first user changed the row. First, it's important to understand the potential problem. Assume that two users U1 and U2 query up the DEPT row with DEPTNO=10. User U1 modifies the Dname in that row and commits. At this point user U2 is looking at a "stale" value in the page in her browser. User U2 proceeds to make her edit and clicks (Commit). In an ADF page implemented in the typical way, the user will correctly get a warning that "Another user has changed the row" as long as U2's application module has not undergone passivation and activation. If instead application load forces ADF to activate the AM's passivated state to service user U2's (Commit)-button click request, then the change made by user U2 is silently committed, potentially overwriting the changes that user U1. This occurs because the act of activating the AM state reads in current DB values of the queried rows, which now reflect the changes made by user U1 instead of the values that are in user U2's current browser page. The solution involves using a change indicator attribute and including that change indicator attribute in the web page as a hidden field. In the example, the Dept entity object is based on the DEPT_WITH_OBJ_VERSION table. This is the standard DEPT table to which has been added a single, additional NUMBER column named OBJECT_VERSION. The ObjectVersion attribute in the Dept entity is marked as a 'Change Indicator' attribute, and it's also marked as a 'History Column' of type 'version number'. The history column setting tells ADF to automatically set the value of this column to 1 in a newly created row, and to increment the version number each time the row is modified and saved. The change indicator setting tells ADF to compare only the value of this attribute in order to determine whether the row has been changed by another user or not. In the absence of a change indicator attribute, ADF must compare the values of all persistent attributes which can take longer. The view1.jspx page uses the h:inputHidden component to include the ObjectVersion attribute value in the page. By doing this, the object version of the row being edited by user U2 will be submitted to the server along with the other attribute values, and it will be used to compare against the ObjectVersion attribute value of the row being edited. Since these values differ, the RowInconsistentException is thrown as desired. Try re-enabling the AM Pooling to convince yourself that the technique will work under normal circumstances as well. To run the example, start by running the CreateTables.sql script to create the DEPT_WITH_OBJ_VERSION table. Then run the view1.jspx page. Once the page appears in your default browser, copy the URL http://localh­ost:701/Signa­lRowInconsiste­nt/faces/view1 and paste it into a different browser. For example, if Google Chrome is your default browser, paste it into Firefox or Internet Explorer. This will allow you to test having two distinct browser users using your application. Both browsers should be looking at the row for DEPTNO=10. In the first browser window, update the value of Dname and click (Commit). Now the second browser is looking at a "stale" value for the Dname. In this second browser, update the value of Loc and click (Commit). The user gets the expected error "Another user has changed the row with primary key oracle.jbo.Key[10]". The AppModule application module in the example has its 'Enable Application Module Pooling' configuration setting (jbo.ampool.doampooling) set to false for testing purposes. Your application module will never have this pooling setting disabled in production, but it is useful for testing the activation-safety of your application module by stress-testing the passivation/activation on each HTTP request. |} See also Steve Muench' [http://blogs.oracle.com/smuenchadf/resource/examples undocumented 10.1.3.x samples] nr. 11

ADF Samples - ADF Business Components

__TOC__ ===Activation/Passivation=== SMU161, SMU115 ... | [[#PLI001|PLI001]] | [http://pastebin.com/raw.php?i=zHbz2ZVD Calling an Oracle database procedure from Java with only ONE line of code] [11.1.1.x] 24-NOV-10 [http://adfplus.blogspot.nl/2010/11/calling-oracle-database-procedure-from.html [[image:info.png]]] |- ||| See also this [http://adfplus.blogspot.nl/2010/12/calling-database-procedure-with-table.html#more follow-up blog post] |} See also Steve Muench' [http://blogs.oracle.com/smuenchadf/resource/examples undocumented 10.1.3.x samples] nr. 100
 
 
Close
loading
Please Confirm
Close