Re: 2.0.4: child DataContext & localObject

From: Marc A. Donis (mad..unbox.com)
Date: Sun Nov 04 2007 - 07:02:01 EST

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

    Thanks, Andrus.

    Should I submit a bug report? If so, can you tell me where I can do so?

    Honestly, I'm a bit surprised that I seem to be the first person ever to
    want to do such a thing. Having a shared DataContext for reference data
    seems like fairly standard practice. Accessing that shared DataContext from
    another DataContext which happens to be a nested context, seems like
    something every app would need to do at some point...

    Regards,
    Marc

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

    > Could be a bug then. Yes, 'localObject' should do the right thing for
    > committed objects.
    >
    > Andrus
    >
    >
    > On Nov 4, 2007, at 12:23 PM, Marc A. Donis wrote:
    >
    >> 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 - 07:07:24 EST