Hi
In 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 correct
The 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
This archive was generated by hypermail 2.0.0 : Wed May 07 2008 - 19:26:05 EDT