This post will show you how to create master-detail form to create master-detail record.
You will find quite many blogs for below requirements :
Master Form and Detail Table -- Keep adding detail record a queried master.
Master Table and Detail Table -- Add master record and then add detail record.
Here fields from both master and detail table are taken in to same ADF form allowing you to create one Master and one Detail record.
I have referred Controlling Entity Posting Order to Avoid Constraint Violations from Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1.6.0).
To start with you will be having entity, association, viewobject and viewlinks created on top of your database table. Once your VO's ( updatable based on entity Objects ) are created, you need understand how you want to populate your primary key Id attribute in Master and detail.
In my sample application, I have populated primary key for master and detail Entities like this :
adf.object.nextVal("DEPARTMENTS_SEQ")
adf.object.nextVal("LOCATIONS_SEQ")
Note that when you are using the above groovy, it means you need to have nextVal method in your EntityImpl. So add below method when using adf.object.nextVal("<sequenceName>").
protected Number nextVal(String sequenceName) {
SequenceImpl s = new SequenceImpl(sequenceName, getDBTransaction());
return s.getSequenceNumber();
}
This is all about setting primary key, where is the master detail form.
From Oracle Link Referred. { Default Post Processing Order :- By default, when you commit the transaction the entity objects in the pending changes list are processed in chronological order, in other words, the order in which the entities were added to the list. This means that, for example, if you create a new
Since you will be calling a commit ( AMDataControl commit method ) from UI, we need to make sure that master gets committed before the detail row. There are couple of ways to do that which are mentioned in the Oracle Link referred.
One way is Compositions changing the default processing order. -- Andrejus Blog explains this.
Other way is overriding postChanges() method to control Posting Order --- Used in this blog.
So here goes the code for DetailEOImpl where postChanges() method is overridden to make sure the master is committed first.
public void postChanges(TransactionEvent e) {
/* If current entity is new or modified */
if (getPostState() == STATUS_NEW ||
getPostState() == STATUS_MODIFIED) {
/* Get the associated Locations for the Department */
LocationsEOImpl location = (LocationsEOImpl)getLocationsEO();
/* If there is an associated location */
if (location != null) {
/* And if it's post-status is NEW */
if (location.getPostState() == STATUS_NEW) {
/*
* Post the location first, before posting this
* entity by calling super below
*/
location.postChanges(e);
}
}
}
System.out.println(" this.getLocationId()-"+this.getLocationId());
super.postChanges(e);
}
Now you are done, just create your ADF form and add commit to the button on Page. it works perfectly fine. In my application, I am calling a AM exposed method as default activity for the taskflow to create the master and detail row ready for entering values. Then added the commit button on page calling datacontrol commit method.
Notes : - You might notice that I have not followed a few steps mentioned in the Oracle link referred. As per section 38.8.3 Overriding postChanges() to Control Post Order steps that needs to be followed are as below :
Sample application can be downloaded from here.
You will find quite many blogs for below requirements :
Master Form and Detail Table -- Keep adding detail record a queried master.
Master Table and Detail Table -- Add master record and then add detail record.
Here fields from both master and detail table are taken in to same ADF form allowing you to create one Master and one Detail record.
I have referred Controlling Entity Posting Order to Avoid Constraint Violations from Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1.6.0).
To start with you will be having entity, association, viewobject and viewlinks created on top of your database table. Once your VO's ( updatable based on entity Objects ) are created, you need understand how you want to populate your primary key Id attribute in Master and detail.
In my sample application, I have populated primary key for master and detail Entities like this :
adf.object.nextVal("DEPARTMENTS_SEQ")
adf.object.nextVal("LOCATIONS_SEQ")
Note that when you are using the above groovy, it means you need to have nextVal method in your EntityImpl. So add below method when using adf.object.nextVal("<sequenceName>").
protected Number nextVal(String sequenceName) {
SequenceImpl s = new SequenceImpl(sequenceName, getDBTransaction());
return s.getSequenceNumber();
}
This is all about setting primary key, where is the master detail form.
From Oracle Link Referred. { Default Post Processing Order :- By default, when you commit the transaction the entity objects in the pending changes list are processed in chronological order, in other words, the order in which the entities were added to the list. This means that, for example, if you create a new
detail record
and then a new master record related to that product, the new detail record
will be inserted first and the new master record
second. } Since you will be calling a commit ( AMDataControl commit method ) from UI, we need to make sure that master gets committed before the detail row. There are couple of ways to do that which are mentioned in the Oracle Link referred.
One way is Compositions changing the default processing order. -- Andrejus Blog explains this.
Other way is overriding postChanges() method to control Posting Order --- Used in this blog.
So here goes the code for DetailEOImpl where postChanges() method is overridden to make sure the master is committed first.
public void postChanges(TransactionEvent e) {
/* If current entity is new or modified */
if (getPostState() == STATUS_NEW ||
getPostState() == STATUS_MODIFIED) {
/* Get the associated Locations for the Department */
LocationsEOImpl location = (LocationsEOImpl)getLocationsEO();
/* If there is an associated location */
if (location != null) {
/* And if it's post-status is NEW */
if (location.getPostState() == STATUS_NEW) {
/*
* Post the location first, before posting this
* entity by calling super below
*/
location.postChanges(e);
}
}
}
System.out.println(" this.getLocationId()-"+this.getLocationId());
super.postChanges(e);
}
Now you are done, just create your ADF form and add commit to the button on Page. it works perfectly fine. In my application, I am calling a AM exposed method as default activity for the taskflow to create the master and detail row ready for entering values. Then added the commit button on page calling datacontrol commit method.
Notes : - You might notice that I have not followed a few steps mentioned in the Oracle link referred. As per section 38.8.3 Overriding postChanges() to Control Post Order steps that needs to be followed are as below :
- 38.8.3.1 Observing the Post Ordering Problem First Hand -- Describes about the problem of commit of master detail.
- 38.8.3.2 Forcing the Supplier to Post Before the Product -- This is what we have done by overriding the postChanges() method.
- 38.8.3.3 Understanding Associations Based on DBSequence-Valued Primary Keys -- This explains what exactly happens when you use DBSequence-Valued Primary Keys. Have you noted that we are populating the primary key from from DBSequence, but ours is not DBSequence-Valued PrimaryKeys. So primary keys in our case gets assigned with proper values as soon as a row is created, where as in case of DBSequence-Valued Primary Keys it is a negative number.
- 38.8.3.4 Refreshing References to DBSequence-Assigned Foreign Keys - We don't need this because we don't have DBSequence-Valued Primary keys.
Sample application can be downloaded from here.