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



Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to