You are correct. The code that does it goes like this: object.setObjectContext(null); object.setObjectId(null); object.setPersistenceState(PersistenceState.TRANSIENT);
I've been thinking about it recently. Rollback by definition wipes out all the uncommitted changes to the ObjectContext and its objects. I think we might preserve ObjectId property. Keeping it around does no harm, even though technically it is a side effect of the object previously being registered with the context. We might change this behavior. I am more hesitant to change the behavior unsetting "objectContext" property. It appears to be a more consequential side effect. I guess we just need an explicit rollback callback invoked prior to kicking the object out. I'll put it on the TODO list for 3.2. In the meantime I guess you'll have to implement some workaround. If you describe what your app does, we can think of a way to catch this. Cheers, Andrus On Mar 6, 2013, at 4:58 PM, Daniel Scheibe <[email protected]> wrote: > Hi Andrus, > > Exactly, i'm dealing with NEW objects. While trying to build a workaround > for a "postRollback" callback i also noticed that the objects are in a > TRANSIENT state after rollbackChanges() was executed. Unfortunately objects > in this state don't contain a lot of useful data anymore (ObjectId, > ObjectContext is gone). > > Cheers, > Daniel > > > 2013/3/6 Andrus Adamchik <[email protected]> > >> Haven't tried to run it yet, but rolling back NEW object transfers them >> into the TRANSIENT state. For this state change postLoad (or any other >> callback) is indeed not invoked. It will be called for rolled back MODIFIED >> and DELETED objects. >> >> So in your application, are you dealing with reverting NEW objects too? >> >> Andrus >> >> On Mar 6, 2013, at 2:16 PM, Daniel Scheibe <[email protected]> >> wrote: >> >>> Hi Andrus, >>> >>> thanks for your feedback. I tried to dig into the Cayenne source code >> from >>> the trunk to see if there actually already is a test case for my >> scenario. >>> Unfortunately i wasn't able to find one so i tried to build one myself >>> (should make it fairly easy to test). Please find my test case below (I >>> hope it is correct as i'm not yet familiar with the Cayenne source code >>> structure) >>> >>> So here is the code (i implemented it in >>> org.apache.cayenne.access.DataContextCallbacksTest): >>> >>> public void testPostLoadCallbacks() { >>> >>> LifecycleCallbackRegistry registry = runtime >>> .getDataDomain() >>> .getEntityResolver() >>> .getCallbackRegistry(); >>> >>> // no callbacks >>> Artist a1 = context.newObject(Artist.class); >>> assertTrue(a1.getPostLoaded() == 0); >>> >>> try { >>> context.commitChanges(); >>> } catch (CayenneRuntimeException cre) { >>> context.rollbackChanges(); >>> assertTrue(a1.getPostLoaded() == 0); >>> } >>> >>> registry >>> .addListener(LifecycleEvent.POST_LOAD, Artist.class, >>> "postLoadCallback"); >>> >>> Artist a2 = context.newObject(Artist.class); >>> assertTrue(a2.getPostLoaded() == 0); >>> >>> try { >>> context.commitChanges(); >>> } catch (CayenneRuntimeException cre) { >>> context.rollbackChanges(); >>> assertTrue(a2.getPostLoaded() > 0); >>> } >>> } >>> >>> Should this test pass successfully or did i do something wrong here (I >>> assume a2.getPostLoaded() should return a non-zero value after a >> rollback)? >>> >>> Thanks in advance! >>> >>> Cheers, >>> Daniel >>> >>> >>> >>> 2013/3/6 Andrus Adamchik <[email protected]> >>> >>>> Hi Daniel, >>>> >>>> Yes, post load callback should be invoked as advertised. I never >>>> personally tried it from a commit catch block, but it should work. Do >> you >>>> have a code sample? Maybe there is a scenario that we do not handle. >>>> >>>>> Is there any chance to get a kind of a "postRollback" lifecycle >> callback >>>>> working or something similar? >>>> >>>> The original callbacks were taken from the JPA spec that doesn't specify >>>> postRollback. We've already diverged from JPA by adding PostAdd. I >> think we >>>> might go further to better reflect Cayenne object lifecycle. So I am >> open >>>> to adding PostRollback in the future (need to think it through though)… >>>> >>>> Andrus >>>> >>>> On Mar 5, 2013, at 6:43 PM, Daniel Scheibe <[email protected]> >>>> wrote: >>>>> All, >>>>> >>>>> i'm trying to get the lifecycle listeners working for my use case and >>>> i've >>>>> come accross a problem. I registered a listener to do some extra stuff >>>> for >>>>> an entity whenever it will be persisted (prePersist) via: >>>>> >>>>> callbackRegistry.addListener(LifecycleEvent.PRE_PERSIST, Content.class, >>>>> "prePersist"); >>>>> >>>>> This get's called as expected and works smoothly. >>>>> >>>>> Now whenever i have the scenario of a CommitException thrown during >>>>> commitChanges() (for whatever reason, underlying database not >> available, >>>>> etc.) i need to revert some of the stuff i did in the "prePersist" >>>>> lifefycle callback on the object in question. >>>>> >>>>> Unfortunately i haven't had luck yet to register a lifecycle listener >>>> that >>>>> will be called in case of a "rollback" through "rollbackChanges". >>>>> >>>>> The documentation states something about "PostLoad" being called >> "Within >>>>> "ObjectContext.rollbackChanges()" after the object is reverted." >>>> (although >>>>> this is from 3.0 i guess it should still apply? >>>>> https://cayenne.apache.org/docs/3.0/lifecycle-callbacks.html) >>>>> >>>>> Is there any chance to get a kind of a "postRollback" lifecycle >> callback >>>>> working or something similar? Or did i just hit a bug with the version >>>> i'm >>>>> using? >>>>> >>>>> Any help is much appreciated. >>>>> >>>>> Cheers, >>>>> Daniel >>>> >>>> >> >>
