Re: 2.0.4: child DataContext & localObject

From: Marc A. Donis (mad..unbox.com)
Date: Sun Nov 04 2007 - 05:23:43 EST

  • Next message: Andrus Adamchik: "Re: 2.0.4: child DataContext & localObject"

    Hi, thanks for the reply.

    The ref object is committed. In fact, it is read-only.

    btw, I found a solution, which I do not like much:

    ..verride
     public void setToOneTarget(String relationshipName, DataObject value,
    boolean setReverse) {
        if (value != null && value.getDataContext() != this.getDataContext()) {
           DataContext dc = getDataContext();
           value = dc.refetchObject(value.getObjectId());
        }
        super.setToOneTarget(relationshipName, value, setReverse);
     }

    Clearly, this results in an unnecessary fetch to bring the reference object
    into the master object's DataContext. I'd still very much like to
    understand why simply doing "value = (DataObject)
    dc.localObject(value.getObjectId(), null);" causes the relationship to be
    reset to null by DataContext.onContextFlush(). Is this a bug?

    Regards,
    Marc

    ----- Original Message -----
    From: "Andrus Adamchik" <andru..bjectstyle.org>
    To: <use..ayenne.apache.org>
    Sent: Sunday, November 04, 2007 09:43
    Subject: Re: 2.0.4: child DataContext & localObject

    > Hi Marc,
    >
    > is the target object ('ref') committed, or is it in some other state
    > (new, modified, etc.)?
    >
    > Andrus
    >
    > On Nov 3, 2007, at 12:36 PM, mad7777 wrote:
    >> Just to follow up... I've tried doing:
    >>
    >>..verride
    >> public void setToOneTarget(String relationshipName, DataObject value,
    >> boolean setReverse) {
    >> if (value != null && value.getDataContext() != this.getDataContext () &&
    >> value.getDataContext() != this.getDataContext()) {
    >> DataContext dc = getDataContext();
    >> value = (DataObject) dc.localObject(value.getObjectId(), value);
    >> value.setPersistenceState(PersistenceState.COMMITTED);
    >> }
    >> super.setToOneTarget(relationshipName, value, setReverse);
    >> }
    >>
    >> ... but alas, the result is the same as below.
    >>
    >> I admit I don't understand what is going on here. It seems that I can't
    >> use
    >> a shared DataContext in conjunction with a nested (i.e. child)
    >> DataContext?
    >> Is this a bug, or am I just going about this all wrong??
    >>
    >> Marc
    >>
    >>
    >>
    >> mad7777 wrote:
    >>>
    >>> Hi,
    >>>
    >>> I am seeing a strange interaction between child DataContexts and
    >>> localObject. If I set a to-one relationship from an object residing in
    >>> a
    >>> child context to another object which lives in that context's parent, I
    >>> see:
    >>>
    >>> org.apache.cayenne.CayenneRuntimeException: [v.2.0.4 October 12 2007]
    >>> Cannot
    >>> set object as destination of relationship abuseStatus because it is in
    >>> a
    >>> different DataContext
    >>>
    >>> So I do:
    >>>
    >>> ..verride
    >>> public void setToOneTarget(String relationshipName, DataObject value,
    >>> boolean setReverse) {
    >>> if (value != null && value.getDataContext() != this.getDataContext()
    >>> &&
    >>> value.getDataContext() != this.getDataContext()) {
    >>> DataContext dc = getDataContext();
    >>> value = (DataObject) dc.localObject(value.getObjectId(), null);
    >>> }
    >>> super.setToOneTarget(relationshipName, value, setReverse);
    >>> }
    >>>
    >>> in the child context object's class, which works fine (but seems like
    >>> it
    >>> should not be necessary?).
    >>>
    >>> But what I really want is:
    >>>
    >>> DataContext refDataContext = DataContext.createDataContext();
    >>> CayenneDataObject ref = ...// get reference from refDataContext
    >>> DataContext userDataContext =
    >>> DataContext.createDataContext().createChildDataContext();
    >>> CayenneDataObject obj =
    >>> userDataContext.createAndRegisterNewObject(MasterObject.class);
    >>> obj.setRef(ref);
    >>>
    >>> In other words, the obj's context (the child context) is not a child of
    >>> the
    >>> referenced object's context.
    >>> In combination with the first bit of code, I now get:
    >>>
    >>> org.apache.cayenne.validation.ValidationException: [v.2.0.4 October 12
    >>> 2007] Validation has failed.
    >>> Validation failure for MasterObject.ref: "ref" is required.
    >>>
    >>> because all the to-one relationship values set in this way are reset to
    >>> null
    >>> during userDataContext.commitChanges()!
    >>>
    >>> The stack looks like this:
    >>>
    >>> MasterObject.setToOneTarget(UnAmourDataObject.java:11) *** value ==
    >>> null in this call
    >>> org.apache.cayenne.access.ChildDiffLoader.arcCreated
    >>> (ChildDiffLoader.java:120)
    >>> org.apache.cayenne.access.ObjectDiff$ArcOperation.apply
    >>> (ObjectDiff.java:428)
    >>> org.apache.cayenne.graph.CompoundDiff.apply(CompoundDiff.java:97)
    >>> org.apache.cayenne.access.ObjectStoreGraphDiff.apply
    >>> (ObjectStoreGraphDiff.java:136)
    >>> org.apache.cayenne.access.DataContext.onContextFlush
    >>> (DataContext.java:1188)
    >>> org.apache.cayenne.access.DataContext.onSync(DataContext.java:1167)
    >>> org.apache.cayenne.access.DataContext.flushToParent
    >>> (DataContext.java:1234)
    >>> org.apache.cayenne.access.DataContext.commitChanges
    >>> (DataContext.java:1138)
    >>>
    >>> Thoughts? Comments? Suggestions?
    >>>
    >>> Thanks,
    >>> Marc
    >>>
    >>>
    >>>
    >>
    >> --
    >> View this message in context: http://www.nabble.com/2.0.4%3A-child-
    >> DataContext---localObject-tf4734281.html#a13561667
    >> Sent from the Cayenne - User mailing list archive at Nabble.com.
    >>
    >>
    >
    >



    This archive was generated by hypermail 2.0.0 : Sun Nov 04 2007 - 05:29:23 EST