Forcing a New Dept to Post Before a New Emp Without Composition Oracle JDeveloper Tip

Forcing a New Dept to Post Before a New Emp Without Composition

Author: Steve Muench, ADF Development Team
Date: March 16, 2005

When two ADF entity objects like Dept and Emp are related by an association that is marked as a composition, one of the automatic framework features this enables is control over their relative post ordering. Specifically, any "owning" Dept entity instance will be posted to the database at commit time before any of its "owned" Emp entity instances to avoid database foreign key constraint violations.

However, if your Dept and Emp entities are associated but not composed, there is no guarantee on the order of posting. In fact, the rule of thumb is that the ADF Business Components framework will post them to the database in the order in time in which they were first added to the transaction list at create, first-attribute-modified, or remove time.

In this situation, it is easy to take control of the post ordering in your own entity object code to guarantee that an associated "parent" is posted before a dependent "child" entity. The technique is to override the postChanges() method in the dependent child EntityImpl subclass, and write code that conditionally forces the parent entity to post first. In the Emp and Dept example, the overridden postChanges() method in the EmpImpl.java class would look like this:

  //=================[ Begin User-Written Code ]=============================
  /**
   * Overridden Framework Method
   *
   * If this Emp entity is new or modified, then check to see whether
   * its owning Dept entity is new, and if so, make sure it gets posted
   * before we call super.postChanges() to post ourself.
   *
   * Note that we check for Emp's status to be either NEW or MODIFIED
   * since the current Emp entity instance might have either:
   *
   *   1. Been created new in the same transaction as its new Dept
   *   2. Been modified in the same transaction to be in a newly-created Dept
   *
   * @param e Framework transaction event
   */
  public void postChanges(TransactionEvent e) {
    if ((getPostState() == STATUS_NEW) || (getPostState() == STATUS_MODIFIED)) {
      EntityImpl myDept = getDept();
      /* If there is an associated department */
      if (myDept != null) {
        /* And if it's post-status is NEW */
        if (myDept.getPostState() == STATUS_NEW) {
          /* Post it first, before posting this entity by calling super below */
          myDept.postChanges(e);
        }
      }
    }
    super.postChanges(e);
  }
  //=================[ End User-Written Code ]=============================

You can try out this code by downloading a small example workspace that illustrates this method in action. After opening the workspace in JDeveloper 10.1.2 and insuring you have a connection named scott pointing to the venerable SCOTT account, right-mouse on the TestModule application module in the project and choose Test... to launch the Business Components Tester.

Try creating a new Employee row, then creating a new department row, then assigning that new department's Deptno value as the new employee's department number. Then commit. The changes get committed without problems. If you comment out the overridden postChanges() method in EmpImpl.java and repeat the same test steps, you'll see that it raises an error at the database level due to having the Emp row post before the Dept row.


NOTE:

If you are working with an Oracle database, another even simpler way to avoid post ordering constraint errors is to make sure that your foreign key constraint between EMP and DEPT tables is defined as DEFERRABLE INITIALLY DEFERRED. The DDL syntax to add such a constraint to the EMP table would look like:

ALTER TABLE EMP ADD (
  CONSTRAINT DEPT_FK FOREIGN KEY (DEPT_ID)
    REFERENCES DEPT (DEPT_ID)
    DEFERRABLE INITIALLY DEFERRED)

Tom Kyte explains the details of this technique in this OTN Magazine Ask Tom column from November/December 2003. If your foreign key is setup like this, then you don't need any overridden postChanges() method even in the plain association case. (Thanks to Leif and Grant for reminding me of this tip!)


E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy