> Under 3.0.2, I have a test that creates a local copy of an object in a > new DataContext, makes a change to it, commits the change, and then > verifies that both the old copy and the new copy match. And this > passes.
Could be because peer context notifications are now asynchronous and you test runs before the change is propagated? Async context synchronization is used for performance reasons and to avoid deadlocks. > It does look like JavaGroupsBridgeFactory gets instantiated as the > default event bridge factory, although if I don't have it installed > (which I don't) it's replaced by a noop event manager. That'll be odd. Has to be something in configs. > So I decided to see whether I could force a refetch for the existing > object in the original database using: > > context.invalidateObjects(this); > context.prepareForAccess(this, null, false); > > prepareForAccess is pulling the old value out of the cachedSnapshots. > This is rather unexpected since invalidateObjects() claims clears out > the cache. The context does this on invalidate: performGenericQuery(new RefreshQuery(objects)); Which, after local invalidation, is propagated to DataDomain, where shared cache invalidation happens. Andrus On Sep 23, 2013, at 11:10 PM, Mike Kienenberger <[email protected]> wrote: > Under 3.0.2, I have a test that creates a local copy of an object in a > new DataContext, makes a change to it, commits the change, and then > verifies that both the old copy and the new copy match. And this > passes. > > Under 3.1, the old object does not reflect the new changes, although > the 3.x docs state that it should by default: > > http://cayenne.apache.org/docs/3.1/cayenne-guide/performance-tuning.html#caching-and-fresh-data > > This appears to be because there's nothing listening for the > postSnapshotsChangeEvent, maybe because there's an error in my > hand-converted modeler test configuration file. > > It does look like JavaGroupsBridgeFactory gets instantiated as the > default event bridge factory, although if I don't have it installed > (which I don't) it's replaced by a noop event manager. > > Ebpp DEBUG [main 09-23 15:42:44] DataRowStore: DataRowStore property > cayenne.DataRowStore.snapshot.expiration = 7200 > Ebpp DEBUG [main 09-23 15:42:44] DataRowStore: DataRowStore property > cayenne.DataRowStore.snapshot.size = 10000 > Ebpp DEBUG [main 09-23 15:42:44] DataRowStore: DataRowStore property > cayenne.DataRowStore.remote.notify = false > Ebpp DEBUG [main 09-23 15:42:44] DataRowStore: DataRowStore property > cayenne.DataRowStore.EventBridge.factory = > org.apache.cayenne.event.JavaGroupsBridgeFactory > > > So I decided to see whether I could force a refetch for the existing > object in the original database using: > > context.invalidateObjects(this); > context.prepareForAccess(this, null, false); > > prepareForAccess is pulling the old value out of the cachedSnapshots. > This is rather unexpected since invalidateObjects() claims clears out > the cache. All I see it doing when I step through the values is > resetting the persistence state from committed to hollow. I don't > see anything in stepping through the code which would remove the cache > snapshot for the data context as documented. > > /** > * Invalidates a Collection of persistent objects. This operation > only applies to the > * objects already committed to the database and does nothing to > the NEW objects. It > * would remove each object's snapshot from caches and change > object's state to > * HOLLOW. On the next access to this object, the object will be refetched. > */ > void invalidateObjects(Collection<?> objects); > > > If I manually remove the item from the cache, then it works, even > without prepareForAccess(). > > ObjectContext context = getObjectContext(); > DataContext dataContext = (DataContext)context; > > dataContext.getObjectStore().getDataRowCache().forgetSnapshot(this.getObjectId()); > context.invalidateObjects(this); > > It seems to me that it's a bug to not invalidate the DataContext > DataRowCache snapshot during invalidateObjects(). >
