Oracle JDeveloper 11gR2 Cookbook
上QQ阅读APP看书,第一时间看更新

Overriding doDML() to populate an attribute with a gapless sequence

In this recipe, we will go over a generic programming technique that you can use to assign gapless database sequence values to entity object attributes. A gapless sequence will produce values with no gaps in between them. The difference between this technique and the one presented in the Using a custom property to populate a sequence attribute recipe, is that the sequence values are assigned during the transaction commit cycle instead of during component creation.

Getting ready

We will add this generic functionality to the custom entity framework class that we created in the Setting up BC base classes recipe in Chapter 1, Pre-requisites to Success: ADF Project Setup and Foundations. The custom framework classes in this case reside in the SharedComponets workspace. You will need access to the HR database schema to run the recipe's test case.

How to do it...

  1. Start by opening the SharedComponets workspace in JDeveloper. If needed, follow the steps in the referenced recipe to create it.
  2. Locate the custom entity framework class in the SharedBC project and open it in the editor.
  3. Click on the Override Methods… icon on the toolbar (the green left arrow) to bring up the Override Methods dialog.
  4. From the list of methods that are presented, select the doDML() method and click OK. JDeveloper will go ahead and insert a doDML() method into the body of your custom entity class.
  5. Add the following code to the doDML() before the call to super.doDML():
    // check for insert operation
    if (DML_INSERT == operation) {
      // iterate all entity attributes
      for (AttributeDef atrbDef :this.getEntityDef().getAttributeDefs()) {
        // check for a custom property called COMMITSEQ_PROPERTY
        String sequenceName=(String)atrbDef.getProperty(COMMITSEQ_PROPERTY);
        if (sequenceName != null) {
          // create the sequence based on the custom property sequence name
          SequenceImpl sequence = new SequenceImpl(sequenceName, this.getDBTransaction());
          // populate the attribute with the next sequence number
          this.populateAttributeAsChanged(atrbDef.getIndex(),
          sequence.getSequenceNumber());
        }
      }
    }

How it works...

If you examine the code presented in this recipe, you will see that it looks similar to the code presented in the Using a custom property to populate a sequence attribute recipe in this chapter. The difference is that this code executes during the transaction commit phase. During this phase, the ADF framework calls the entity's doDML() method. In our overridden doDML(), we first check for a DML_INSERT operation flag. This would be the case when inserting a new record into the database. We then iterate the entity's attribute definitions looking for a custom property identified by the constant COMMITSEQ_PROPERTY . Based on the property's value, we create a sequence object and get the next sequence value by calling getSequenceNumber() . Finally, we assign the sequence value to the specific attribute by calling populateAttributeAsChanged() . Assigning a sequence value during the commit phase does not allow the user to intervene. This will produce gapless sequence values. Of course to guarantee that there are no final gaps in the sequence values, deletion should not be allowed. That is, if rows are deleted, gaps in the sequence values will appear. Gaps will also appear in case of validation failures, if you do not subsequently rollback the transaction. Since all of the entity objects are derived from the custom entity framework class, all object commits will go through this doDML() implementation.

To use this technique, first you will need to re-deploy the shared components project. Then add the CommitSequence custom property as needed to the specific attributes of your entity objects. We explained how to do this in the Using a custom property to populate a sequence attribute recipe.

There's more...

doDML() is called by the ADF framework during a transaction commit operation. It is called for every entity object in the transaction's pending changes list. This is true even when entity Update Batching optimization is used. For an entity-based view object, this means that it will be called for every row in the row set that is in the pending changes list. The method accepts an operation flag; DML_INSERT , DML_UPDATE , or DML_DELETE to indicate an insert, update, or delete operation on the specific entity.

Data is posted to the database once super.doDML() is called, so any exceptions thrown before calling super.doDML() will result in no posted data. Once the data is posted to the database, queries or stored procedures that rely upon the posted data should be coded in the overridden application module's beforeCommit() method. This method is also available at the entity object level, where it is called by the framework for each entity in the transaction's pending changes list. Note that the framework calls beforeCommit() for each entity object in the transaction pending changes list prior to calling the application module beforeCommit().

For additional information on doDML(), consult the sections Methods You Typically Override in Your Custom EntityImpl Subclass and Transaction "Post" Processing (Record Cache) in the Fusion Developer's Guide for Oracle Application Development Framework,which can be found at http://docs.oracle.com/cd/E24382_01/web.1112/e16182/toc.htm.

Note

Note that for testing purposes, we have created a Department entity object in the HRDepartments workspace and added the CommitSequence custom property to its DepartmentId attribute. The value of the CommitSequence property was set to DEPARTMENTS_SEQ, the database sequence that is used to assign values to the DepartmentId attribute. To test the recipe, run the DepartmentAppModule application module on the ADF Model Tester .

See also

  • Breaking up the application in multiple workspaces, Chapter 1, Pre-requisites to Success: ADF Project Setup and Foundations
  • Setting up BC base classes, Chapter 1, Pre-requisites to Success: ADF Project Setup and Foundations
  • Using a custom property to populate a sequence attribute, in this chapter
  • Creating and applying property sets, in this chapter