Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers 10g (10.1.3.1.0) Part Number B25947-01 |
|
|
View PDF |
Note: To experiment with the example described in this section, use the sameControllingPostingOrder project in the AdvancedEntityExamples workspace used in Section 26.7, "Controlling Entity Posting Order to Avoid Constraint Violations". |
When you create a view object with multiple entity usages, you can enable a secondary entity usage to be updatable by selecting it in the Selected list of the Entity Objects panel of the View Object Editor and:
Selecting the Reference checkbox
Deselecting the Updatable checkbox
If you only plan to use the view object to update or delete existing data, then this is the only step required. The user can update attributes related to any of the non-reference, updatable entity usages and the view row will delegate the changes to the appropriate underlying entity rows.
However, if you need a view object with multiple updatable entities to support creating new rows, then you need to write a bit of code to enable that to work correctly. When you call createRow()
on a view object with multiple update entities, it creates new entity row parts for each updatable entity usage. Since the multiple entities in this scenario are related by an association, there are three pieces of code you might need to implement to ensure the new, associated entity rows can be saved without errors:
You may need to override the postChanges()
method on entity objects involved to control the correct posting order.
If the primary key of the associated entity is populated by a database sequence using DBSequence
, and if the multiple entity objects are associated but not composed, then you need to override the postChanges()
and refreshFKInNewContainees()
method to handle cascading the refreshed primary key value to the associated rows that were referencing the temporary value.
You need to override the create()
method of the view object's custom view row class to modify the default row creation behavior to pass the context of the parent entity object to the newly-created child entity.
In Section 26.7, "Controlling Entity Posting Order to Avoid Constraint Violations", you've already seen the code required for 1 and 2 above in an example with associated Product
and ServiceRequest
entity objects. The only thing remaining is the overridden create()
method on the view row. Consider a ServiceRequestAndProduct
view object with a primary entity usage of ServiceRequest
and secondary entity usages of Product
and User
. Assume the Product
entity usage is marked as updatable and non-reference, while the User
entity usage is a reference entity usage.
Example 27-31 shows the commented code required to correctly sequence the creation of the multiple, updatable entity row parts during a view row create operation.
Example 27-31 Overriding View Row create() Method for Multiple Updatable Entities
/** * By default, the framework will automatically create the new * underlying entity object instances that are related to this * view object row being created. * * We override this default view object row creation to explicitly * pre-populate the new (detail) ServiceRequestImpl instance using * the new (master) ProductImpl instance. Since all entity objects * implement the AttributeList interface, we can directly pass the * new ProductImpl instance to the ServiceRequestImpl create() * method that accepts an AttributeList. */ protected void create(AttributeList attributeList) { // The view row will already have created "blank" entity instances ProductImpl newProduct = getProduct(); ServiceRequestImpl newServiceRequest = getServiceRequest(); try { // Let product "blank" entity instance to do programmatic defaulting newProduct.create(attributeList); // Let service request "blank" entity instance to do programmatic // defaulting passing in new ProductImpl instance so its attributes // are available to the EmployeeImpl's create method. newServiceRequest.create(newProduct); } catch (JboException ex) { newProduct.revert(); newServiceRequest.revert(); throw ex; } catch (Exception otherEx) { newProduct.revert(); newServiceRequest.revert(); throw new RowCreateException(true /* EO Row? */, "Product" /* EO Name */, otherEx /* Details */); } }
In order for this view row class to be able to invoke the protected create()
method on the Product
and ServiceRequest
entity objects, they need to override the create()
method. If the view object and entity objects are in the same package, the overridden create()
method can have protected access. Otherwise, it requires public
access.
/** * Overridding this method in this class allows friendly access * to the create() method by other classes in this same package, like the * ServiceRequestsAndProduct view object implementation class, whose overridden * create() method needs to call this. * @param nameValuePair */ protected void create(AttributeList nameValuePair) { super.create(nameValuePair); }