HiIn our application we are using LOCAL_CACHE and cache keys to refresh it, but only for a special context called 'shared' . We have overridden the CayenneContext commitChanges with following to ensure cache invalidation on every commit :
if (!isSharedContext()) { try { List<Class> commitedClasses = new Vector<Class>(); for (Object o : uncommittedObjects())if (!commitedClasses.contains(o.getClass()) && o instanceof PersistentObject)
commitedClasses.add(o.getClass()); super.commitChanges(); for (Class<? extends PersistentObject> c : commitedClasses) {performGenericQuery(new RefreshQuery(new String[] { PersistentObject.defaultCacheKeyForEntity(c) }));
} } catch (CayenneRuntimeException e) { runtimeExceptionThrown(e, false); } } else {logger.error("Attempt to save shared context", new IllegalStateException("Shared context is read-only"));
}whenever a select query is executed we are setting the cache policy and keys
if (query instanceof SelectQuery) { SelectQuery sq = ((SelectQuery) query); if (isSharedContext) { // if the query is on the shared context then use cache // sq.setCachePolicy(QueryMetadata.LOCAL_CACHE);// if the root class of the query is kind of PersistentObject then use the cache keys if (sq.getRoot() instanceof Class && PersistentObject.class.isAssignableFrom((Class<? extends PersistentObject>) (sq.getRoot()))) { Class<? extends PersistentObject> c = (Class<? extends PersistentObject>) sq.getRoot();
List<String> currentCacheGroups = new Vector<String>(); if (sq.getCacheGroups() != null) currentCacheGroups = Arrays.asList(sq.getCacheGroups()); String key = PersistentObject.defaultCacheKeyForEntity(c); if (!currentCacheGroups.contains(key)) { currentCacheGroups.add(key); sq.setCacheGroups(currentCacheGroups.toArray(new String[] {})); } } } }This works nicely, but there is one problem: the relationship query does not return refreshed values.
An example. there are two views: One is a list of artists with painting counts, the counts are calculated using relationship (anArtist.getPaintings().size()). The second is a simple list of paintings.
1) client app 1: artists list shows: Monet - 5 Malevich - 4 vanGogh - 3 painting list contains 12 lines client app 2 adds a new painting for vanGogh, it lists now Monet - 5 Malevich - 4 vanGogh - 4 painting list contains 13 lines client app 1 lists the artists again: Monet - 5 Malevich - 4 vanGogh - 3 <- incorrect painting list contains 13 records, which is correctThe odd thing is also that for a given client application both lists (artist and painting) are using the same context, so if the record is there, why it does not show up when accessed via relationship ?
Is there something I'm doing wrong ? Is there a way to force the RelationshipQuery to refresh ?
We are using Cayenne build from sources about a month ago (svn 642725). Marcin
smime.p7s
Description: S/MIME cryptographic signature