|
Setting Up and Correctly Inserting Into Child Views with Two Masters
Sometimes it's necessary to create a data model in which a "child" view object has two different parent views. There are two things that trip up developers using BC4J when trying to work with such a combination:
- Setting up the data model in the first place with two masters controller the same child view instance
- Inserting a new row in the child view if one or both of the masters uses composition in its association to the child entity involved.
This quick article (and the downloadable sample) should help clear things up.
If you want to try this at home with JDeveloper 9.0.3 or later, download the InsertingWithTwoComposedMasters.zip file that contains the project. I opened this project in JDeveloper 9.0.5.1.1536 (which is the post-preview build I'm using on my laptop today) and dropped the application module into a new BC4J Diagram to produce the picture at left. You can run the CreateTable.sql script in the project against your SCOTT account to create the three underlying tables that the demo requires.
By default, the BC4J design time reverse-engineered appropriate associations and viewlinks to mirror the FOREIGN KEY ... ON DELETE CASCADE referential integrity constraints that were used when the tables got created. To create this data model, I did the following in the application module wizard:
- Removed all of the VO instances that the reverse-engineering had defaulted for me
- Added a view object instance named "ParentOneView" of the test.ParentOneView view object to the data model
- Added a view object instance named "ParentTwoView" of the test.ParentTwoView view object to the data model
- Selected the "ParentOneView" in the "Data Model" tree, selected the "ChildWithTwoParentsView" that is indented beneath ParentOneView in the "Available View Objects" tree, edited the default instance name of "ChildWithTwoParentsView1" in the "Name" to read "ChildWithTwoParentsView", and finally pressed the ">" button to add the child view instance.
- Selected the "ParentTwoView" in the "Data Model" tree, selected the "ChildWithTwoParentsView" that is indented beneath ParentTwoView in the "Available View Objects" tree, edited the default instance name of "ChildWithTwoParentsView1" in the "Name" to read "ChildWithTwoParentsView" -- again, using the same instance name as the already-existing instance in the data model -- and finally pressed the ">" button to add the child view instance.
- Confirmed the alert asking whether I really mean to use the same VO instance name as the child of this view as well (which I do in this case!)
The TestClient.java class in the downloadable sample zip file illustrates two correct ways to insert a new child row, when both masters are composing and required to avoid the InvalidOwnerException. This article explains some of the reasons why you might receive that error.
One of the techniques involves using the createAndInitRow() API on the RowSetIterator interface (which ViewObject extends) in order to create a new row with its required foreign key attribute values as well as its descriminator attributes value(s) if appropriate.
The second technique involves making a row current in both of the master views first, then using the normal createRow() API to create the row. The two view links will automatically handle filling in the foreign key values of their respective current master row for you.
|