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!)
|
|