Re: 2.0.4: child DataContext & localObject

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Sun Nov 04 2007 - 07:12:18 EST

  • Next message: Kevin Menard: "Re: localObject vs prefetches: would there be a benefit ?"

    Yes, I am surprised too, but I need to try it, before I can come to
    any conclusion.

    Cayenne bug tracker is located here:

    https://issues.apache.org/cayenne/

    Andrus

    On Nov 4, 2007, at 2:02 PM, Marc A. Donis wrote:

    > 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:12:51 EST