Skip to main content
This revision made June 08, 2012 12:27, 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 Two Approaches to Referencing Controller-layer Session State in VO Bind Variables [11.1.1.2] 16-DEC-2009]
This example illustrates two different approaches to referencing controller layer state inside the default value expression of a view object's bind variable. One typical example is to reference the name of the logged-in user (which in the past web applications would store in a Web session attribute), however since you can use the adf.context.securityContext.userName groovy expression to reference the username of the logged-in user when using ADF Security, I choose a slightly-different example of storing a code representing the user's favorite color. The ViewController project contains a UserInfo bean with a single favoriteColor property. This bean is registered in the adfc-config.xml file as a session-scoped managed bean, and using the JSF managed property feature, the default value of emgreen is injected into the bean at creation time. The Model project contains two view objects that each contain a bind variable named VarFavoriteColor whose default value we'd like to come from the current value of the aforementioned UserInfo managed bean's favoriteColor property. There are two basic approaches: one will appeal more to those who cherish the cleanest logical separation of view/controller and model layers. The other appeals more to developers who like to use the "simplest thing that works" (as long as it's not bad practice). The ExampleVO2 VO instance in the AM data model is of type ExampleVOUsi­ngADFContext­SessionInfoI­nBindVariable. This view object's VarFavoriteColor bind variable references the groovy expression adf.context­.sessionScop­e.UserInfo.f­avoriteColor and represents the "simplest thing that works" approach. This takes advantage of the fact that ADFContext object abstracts access to the four interesting scopes that might be relevant during runtime of an ADF application: applicationScope, sessionScope, viewScope, and requestScope. When running in the web container, these scopes map onto the obvious matching scopes that you are familiar with from the view/controller layer. When running outside the web container, the ADFContext provides a default implementation of these scopes as a set of static maps that are useful for regression testing purposes. The Test class in the Testing project illustrates making use of the ADFContext.getSessionScope() to setup the session-level information the view object is expecting to find at runtime. The ExampleVO in the AM's data model is of type ExampleVOUsingCo­ntrollerSuppliedU­serDataHashtableI­nfoInBindVariable. This view object's bind variable of the same name references the groovy expression adf.userSession.userData.FavoriteColor. In this implementation that defines the more clear separation of view/controller layer and business tier - which is the one I personally prefer and recommend - the ADFBC session's userData map is used to store information that the view object's bind variable will reference. In a customized data control implementation class (CustomDCJboDataControl), the beginRequest method is overridden to invoke a setSessionFavoriteColor() method on the ExampleModule client interface to pass in the value of the UserInfo.favoriteColor into the business tier. The application module stores this information in the user data map, and makes that information activation/passivation-safe by overriding the passivateState() and activateState() methods. The custom data control is configured by setting the fully-qualified name of the CustomDCJboDataControlFactory class in the ExampleModuleDataControl entry's FactoryClass property in the DataBindings.cpx file (in the dataControlUsages section). On each request, the view/controller layer passes this information into the business layer, and the ExampleVOUsingCo­ntrollerSuppliedU­serDataHashtableI­nfoInBindVariable view object references its value from the userData map. Notice the setDefaultV­aluesForSess­ionLevelFav­oriteColor() method in the ExampleModuleImpl class. This is invoked in an overridden prepareSession() method to assign a reasonable default value to both of the favoriteColor elements if their value is currently null. This would ensure that both approaches would work if the respective view object were called from a service or a test client that didn't provide any specific value at runtime. In the Testing project, the Test class illustrates how you can write a standalone regression test (just a simple Java class in this example, not a JUnit test) which mimics the view/controller layer calling of the setSessionFavoriteColor() API in the one case, and which populates a "mock" sessionScope UserInfo bean with a favoriteColor property to make the other view object find its expected information. As mentioned above I prefer the approach that uses the userData hash table set explicitly via an application module method, however at least now you have a good example of both techniques in action so you can decide for yourself which you prefer.
AAP001 [link text ] [11.1.1.x] date

See also Steve Muench' undocumented 10.1.3.x samples nr. 118 and 126

Calling PL/SQL in Database

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

Control Hints

SMU137 Implementing Custom View Row Hint Behavior [11.1.1.0.0] 9-DEC-2008
This example illustrates how to provide a custom view row attribute hints implementation. The EmpViewRow class overrides the createViewRowAttrHints method to return a new instance of the EmpViewRowAttributeHintsImpl class (which extends the framework base class ViewRowAttrHints. In the EmpViewRowAttributeHintsImpl class, notice that we've overridden the getHint() API to conditionally return a value for user-defined attribute hints named "mindate" and "maxdate". These hints are coded to look at the value of the Hiredate in the current row, and return a date String that represents three days before that date for "mindate" and three days after that date for "maxdate". The class also overrides the getLabel API to customize the value of the "label" UI hint for the Job attribute. Run the TestPage.jspx and try to edit a "Hiredate" value. You'll see that the date picker only allows you to change the date to a date that is within a span of three days before to three days after the current value. This occurs due to the UI component's referencing the custom "mindate" and "maxdate" hints appropriately. Also, you'll notice that the label for the "Job" field is the default label with the value of the Sal attribute appended to it.

Customizations/Extensions

See Steve Muench' undocumented 10.1.3.x samples nr. 131

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

View Objects

SMU141 Automatic Runtime Query/Join Pruning with Declarative View Objects [11.1.1.0, HR schema 20-DEC-2008
This example contains a single EmployeeAllInfo view whose SQL mode is set to use the new-in-11g setting of 'Declarative'. It contains one editable Employees entity usage, and six additional reference entity usages showing related information about the employee's department, the department's manager, the department's location, the department's region, the employee's job, and the department's country. When a view object is in declarative mode, its SQL statement is determined at runtime instead of at design time. Attributes in the view object can have their Selected in Query property set to false, and these attributes will only be selected if they are referenced by the page definition for the current page, otherwise they will be left out of the query. When multiple entity usages are involved, if all the attributes from a given entity usage are left out of the query, then the ADFBC runtime "prunes" that table related to that entity usage out of the query and does not perform that join. The application module in the Model project includes three different instances of the same EmployeeAllInfo view object. You can observe the different runtime queries performed by the three different JSPX pages by looking in the log while performing a search in each page. The file Queries.txt included in the ViewController project contains a formatted version of the different queries. You can see in the query for the MinimalEmployeeInfo.jspx page, that only the EMPLOYEES table is included. In the query for MediumEmployeeInfo.jspx you see EMPLOYEES, DEPARTMENTS, EMPLOYEES (a second time for the manager), and JOBS. The query for the final page joins all of the tables.
Difference compared to previous revision
===Customizations/Extensions=== See Steve Muench' [http://blogs.oracle.com/smuenchadf/resource/examples undocumented 10.1.3.x samples] nr. 131 ===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 ===Vi

ADF Samples - ADF Business Components

__TOC__ ===Activation/Passivation=== {| border="1" ... | [http://java.net/projects/smuenchadf/sources/samples/content/DeclarativeVOPruning.zip Automatic Runtime Query/Join Pruning with Declarative View Objects [11.1.1.0, HR schema] 20-DEC-2008 |- ||| This example contains a single EmployeeAllInfo view whose SQL mode is set to use the new-in-11g setting of 'Declarative'. It contains one editable Employees entity usage, and six additional reference entity usages showing related information about the employee's department, the department's manager, the department's location, the department's region, the employee's job, and the department's country. When a view object is in declarative mode, its SQL statement is determined at runtime instead of at design time. Attributes in the view object can have their Selected in Query property set to false, and these attributes will only be selected if they are referenced by the page definition for the current page, otherwise they will be left out of the query. When multiple entity usages are involved, if all the attributes from a given entity usage are left out of the query, then the ADFBC runtime "prunes" that table related to that entity usage out of the query and does not perform that join. The application module in the Model project includes three different instances of the same EmployeeAllInfo view object. You can observe the different runtime queries performed by the three different JSPX pages by looking in the log while performing a search in each page. The file Queries.txt included in the ViewController project contains a formatted version of the different queries. You can see in the query for the MinimalEmployeeInfo.jspx page, that only the EMPLOYEES table is included. In the query for MediumEmployeeInfo.jspx you see EMPLOYEES, DEPARTMENTS, EMPLOYEES (a second time for the manager), and JOBS. The query for the final page joins all of the tables. |} ===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
 
 
Close
loading
Please Confirm
Close