Subject: SDO 120 - Projection & Undefined State
Before SDO 3.0 goes to public review, I want to be sure we all agree on the behaviour of the project operation (http://www.osoa.org/jira/browse/SDO-120 ). As a means to move data from one HelperContext to another HelperConext we (Oracle) find the project method quite useful, our concern lies in the following constraint:
DataObject O1 = hc1.getDataFactory().create(...);
DataObject O2 = hc2.getDataHelper().project(O1);
O1 == hc1.getDataHelper().project(O2);
It is this constraint that according to section 4.14.3, "The project operation leaves the DataObject O1, and all objects in the transitive closure reachable from O1 in an undefined state.". My interpretation of "undefined state" is that this DataObject is not guaranteed to work correctly if you try to use it. This constraint is non-trivial to implement and not without is problems (see Problematic Use Cases 1 & 2 below), so we need to agree that the constraint is worth having.
Primary Use Case - Applying an XML Representation
Once we moved from tree's to graphs we needed a new way to apply an XML structure to our DataObjects. In this scenario you would have two HelperContexts, one with metadata based on a data source (graph) and another based on an XML schema (tree). When you want to send the results of a data source query as XML you simply project between HelperContexts. Note that in this scenario the DataObjects representing the data source data are in an undefined state until the XML HelperContext passes control back:
DataObject dataSourceDO = // obtained from data source some how
DataObject xmlDO = xmlHelperContext.getDataHelper().project(dataSourceDO); // dataSourceDO is now in undefined state
dataSourceHelperContext.getDataHelper().project(xmlDO); // dataSourceDO is back to a define state
In this scenario, the DataObject is never modified in the XML HelperContext, but had to exist in an undefined state regardless.
Problematic Use Case 1 - DataObject Shared by 2 Graphs
In this use case DataObjects O1 & O3 both have a reference to DataObject O2.
Before Projection: O1 --non-containment --> O2 <--non-containment-- O3
After Projection of 01: O1 (undefined state) --non-containment --> O2 (undefined state) <--non-containment-- O3
This means that after O1 is projected, DataObject O3 is in a defined state, but O2 which it is referencing is not.
Problematic Use Case 2 - Dereferenced Objects
What happens to objects that have been dereferenced while projected? Presumably it becomes the responsibility of the person who dereferenced the object to project it back to the original HelperContext? If so how does that person know that a projection is necessary and where to project it back to?
HelperContext 1: O1 --non-containment--> O2
HelperContext 2: O1' = hc2.getDataHelper().project(O1);
HelperContext 2: O1'.getDataObject("o2").detach();
HelperContext 1: hc1.project(O1'); leaves O2 in an undefined state?