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); c1.commitChanges(); // 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. Andrus > On Apr 12, 2017, at 4:50 AM, Michael Gentry <blackn...@gmail.com> 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 <and...@objectstyle.org> > 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 <blackn...@gmail.com> 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 >> >>