cayenne-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrus Adamchik <>
Subject Re: localObject() behavior
Date Thu, 13 Apr 2017 14:51:59 GMT
Yes, this was a breaking change. The old "localObject" was used by the internal code, but was
also exposed as public API. So it tried to be everything to everybody. Calling it required
checking a bunch of preconditions, and it was generally hard to understand what it would do
in any given situation.

The current "localObject" is arguably easier to understand as it deals with a very specific
case: mapping an object from one context to the *same* object in the other. This necessarily
limits us to creating a HOLLOW object (that will throw if it can't resolve its state from
parent), as doing anything else would violate two objects equality expectations:

T t1 = c1.newObject(T.class);
T t2 = c2.localObject(t1);


// t1 no longer corresponds to t2 under the old "localObject" ; under the new it will throw
on access.

So yeah, if you need a different flavor of this operation that copies uncommitted state, you
will need to implement it on your own. If it is a common enough case, and we can clearly define
what it does, perhaps we'll find a place for it in Cayenne core.


> On Apr 12, 2017, at 4:50 AM, Michael Gentry <> wrote:
> Well, these are all peer contexts and rely heavily on the old behavior of
> the prototype values being copied over ...
> On Tue, Apr 11, 2017 at 2:49 PM, Andrus Adamchik <>
> wrote:
>>> Anyone know why making a local object copy of a NEW object will set the
>>> copy to HOLLOW which will try to trigger faults later?
>> This is a valid situation in case of nested contexts. If you use
>> 'localObject' on an object from a parent context, copying it to a child
>> context, it will resolve from HOLLOW by checking the parent.
>> Andrus
>>> On Apr 10, 2017, at 7:38 AM, Michael Gentry <> wrote:
>>> I'm converting an application from 3.0 to 3.1 and was fixing all the
>>> localObject() calls to be the simpler version introduced in 3.1.  One
>> thing
>>> I encountered was a utility method:
>>>   public static <T extends CayenneDataObject> T copyToContext(T
>>> cayenneObject, DataContext dataContext)
>>>   {
>>>       T copiedObject =
>>> dataContext.localObject(cayenneObject.getObjectId(), cayenneObject);
>>>       // The returned copy is HOLLOW, make the copy NEW if the original
>>> is NEW.
>>>       if (cayenneObject.getPersistenceState() == PersistenceState.NEW)
>>>           copiedObject.setPersistenceState(PersistenceState.NEW);
>>>       return copiedObject;
>>>   }
>>> I tried removing this utility method and just use the new localObject(),
>>> but exceptions (such as FaultFailureException) started being thrown.  (I
>>> won't even try to explain why so many local object copies of
>> non-persisted
>>> objects are being used.)
>>> Anyone know why making a local object copy of a NEW object will set the
>>> copy to HOLLOW which will try to trigger faults later?
>>> Thanks,
>>> mrg

View raw message