You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by "Marc A. Donis" <ma...@runbox.com> on 2007/11/01 22:42:41 UTC

2.0.4: child DataContext & localObject

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:

 @Override
 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


Re: 2.0.4: child DataContext & localObject

Posted by Andrus Adamchik <an...@objectstyle.org>.
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"  
> <an...@objectstyle.org>
> To: <us...@cayenne.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:
>>>
>>> @Override
>>> 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"  
>>> <an...@objectstyle.org>
>>> To: <us...@cayenne.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:
>>>>>
>>>>> @Override
>>>>> 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:
>>>>>>
>>>>>>  @Override
>>>>>>  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.
>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
>


Re: 2.0.4: child DataContext & localObject

Posted by "Marc A. Donis" <ma...@runbox.com>.
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" <an...@objectstyle.org>
To: <us...@cayenne.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:
>>
>> @Override
>> 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" 
>> <an...@objectstyle.org>
>> To: <us...@cayenne.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:
>>>>
>>>> @Override
>>>> 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:
>>>>>
>>>>>  @Override
>>>>>  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.
>>>>
>>>>
>>>
>>
>>
>
> 


Re: 2.0.4: child DataContext & localObject

Posted by Andrus Adamchik <an...@objectstyle.org>.
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:
>
> @Override
> 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"  
> <an...@objectstyle.org>
> To: <us...@cayenne.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:
>>>
>>> @Override
>>> 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:
>>>>
>>>>  @Override
>>>>  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.
>>>
>>>
>>
>
>


Re: 2.0.4: child DataContext & localObject

Posted by "Marc A. Donis" <ma...@runbox.com>.
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:

 @Override
 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" <an...@objectstyle.org>
To: <us...@cayenne.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:
>>
>> @Override
>> 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:
>>>
>>>  @Override
>>>  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.
>>
>>
>
> 


Re: 2.0.4: child DataContext & localObject

Posted by Andrus Adamchik <an...@objectstyle.org>.
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:
>
> 	@Override
> 	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:
>>
>>  @Override
>>  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.
>
>


Re: 2.0.4: child DataContext & localObject

Posted by mad7777 <ma...@runbox.com>.
Just to follow up... I've tried doing:

	@Override
	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:
> 
>  @Override
>  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.