Author: aadamchik
Date: Mon Aug 21 02:16:42 2006
New Revision: 433202

URL: http://svn.apache.org/viewvc?rev=433202&view=rev
Log:
CAY-632 - done except "invalidate all" functionality

Added:
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/RefreshQueryInContextTst.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/resources/dml/access.RefreshQueryInContextTst.xml
Removed:
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/query/InvalidateListCacheQuery.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/query/InvalidateListCacheQueryTst.java
Modified:
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContext.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/ObjectStore.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/query/RefreshQuery.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/DataContextTst.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/ObjectStoreTst.java
    
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/query/RefreshQueryTst.java

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
 Mon Aug 21 02:16:42 2006
@@ -19,14 +19,15 @@
 
 package org.apache.cayenne;
 
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.cayenne.cache.QueryCache;
-import org.apache.cayenne.query.InvalidateListCacheQuery;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.query.RefreshQuery;
 import org.apache.cayenne.remote.RemoteIncrementalFaultList;
-import org.apache.cayenne.util.GenericResponse;
 import org.apache.cayenne.util.ListResponse;
 import org.apache.cayenne.util.ObjectContextQueryAction;
 
@@ -45,7 +46,7 @@
 
         if (interceptOIDQuery() != DONE) {
             if (interceptRelationshipQuery() != DONE) {
-                if (interceptInvalidateQuery() != DONE) {
+                if (interceptRefreshQuery() != DONE) {
                     if (interceptLocalCache() != DONE) {
                         if (interceptPaginatedQuery() != DONE) {
                             runQuery();
@@ -84,8 +85,7 @@
             return !DONE;
         }
 
-        QueryCache queryCache = ((CayenneContext) actingContext)
-                .getQueryCache();
+        QueryCache queryCache = ((CayenneContext) 
actingContext).getQueryCache();
         if (cache) {
 
             List cachedResults = queryCache.get(metadata);
@@ -102,32 +102,68 @@
         queryCache.put(metadata, response.firstList());
         return DONE;
     }
-    
-    private boolean interceptInvalidateQuery() {
-        if (query instanceof InvalidateListCacheQuery) {
-            InvalidateListCacheQuery invalidateQuery = 
(InvalidateListCacheQuery) query;
-            
-            QueryCache queryCache = ((CayenneContext) 
actingContext).getQueryCache();
 
-            if (invalidateQuery.getQueryNameKey() != null) {
-                queryCache.remove(invalidateQuery.getQueryNameKey());
-            }
+    private boolean interceptRefreshQuery() {
+        if (query instanceof RefreshQuery) {
+            RefreshQuery refreshQuery = (RefreshQuery) query;
+
+            CayenneContext context = (CayenneContext) actingContext;
+
+            // handle three separate scenarious, but do not combine them as it 
will be
+            // unclear how to handle cascading behavior
+
+            // 1. invalidate object collection
+            Collection objects = refreshQuery.getObjects();
+            if (objects != null && !objects.isEmpty()) {
+
+                CayenneContextGraphManager graphManager = 
context.internalGraphManager();
+
+                Iterator it = objects.iterator();
+                while (it.hasNext()) {
+                    Persistent object = (Persistent) it.next();
+
+                    // we don't care about NEW objects,
+                    // but we still do care about HOLLOW, since snapshot might 
still be
+                    // present
+                    if (object.getPersistenceState() == PersistenceState.NEW) {
+                        continue;
+                    }
+
+                    object.setPersistenceState(PersistenceState.HOLLOW);
 
-            String[] groupKeys = invalidateQuery.getGroupKeys();
-            if (groupKeys != null && groupKeys.length > 0) {
-                for (int i = 0; i < groupKeys.length; i++) {
-                    queryCache.removeGroup(groupKeys[i]);
+                    // remove cached changes
+                    
graphManager.changeLog.unregisterNode(object.getObjectId());
+                    graphManager.stateLog.unregisterNode(object.getObjectId());
                 }
-            }
 
-            if (invalidateQuery.isCascade()) {
+                // cascade
                 return !DONE;
             }
-            else {
-                GenericResponse response = new GenericResponse();
-                response.addUpdateCount(1);
-                this.response = response;
+            // 2. refresh query - have to do it eagerly to refresh the objects 
involved
+            else if (refreshQuery.getQuery() != null) {
+                Query cachedQuery = refreshQuery.getQuery();
+
+                String cacheKey = cachedQuery
+                        .getMetaData(context.getEntityResolver())
+                        .getCacheKey();
+                context.getQueryCache().remove(cacheKey);
+
+                this.response = context.performGenericQuery(cachedQuery);
+
+                // do not cascade to avoid running query twice
                 return DONE;
+            }
+            // 3. refresh groups...
+            else if (refreshQuery.getGroupKeys() != null
+                    && refreshQuery.getGroupKeys().length > 0) {
+
+                String[] groups = refreshQuery.getGroupKeys();
+                for (int i = 0; i < groups.length; i++) {
+                    context.getQueryCache().removeGroup(groups[i]);
+                }
+
+                // cascade group invalidation
+                return !DONE;
             }
         }
 

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContext.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContext.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContext.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContext.java
 Mon Aug 21 02:16:42 2006
@@ -71,6 +71,7 @@
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.query.RefreshQuery;
 import org.apache.cayenne.util.EventUtil;
 import org.apache.cayenne.util.GenericResponse;
 import org.apache.cayenne.util.Util;
@@ -873,14 +874,14 @@
     }
 
     /**
-     * "Invalidates" a Collection of DataObject. This operation would remove 
each object's
-     * snapshot from cache and change object's state to HOLLOW. On the next 
access to this
-     * object, it will be refetched.
+     * "Invalidates" a Collection of persistent objects. This operation would 
remove each
+     * object's snapshot from cache and change object's state to HOLLOW. On 
the next
+     * access to this object, it will be refetched.
      * 
      * @see #unregisterObjects(Collection)
      */
-    public void invalidateObjects(Collection dataObjects) {
-        getObjectStore().objectsInvalidated(dataObjects);
+    public void invalidateObjects(Collection objects) {
+        performGenericQuery(new RefreshQuery(objects));
     }
 
     /**

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
 Mon Aug 21 02:16:42 2006
@@ -19,17 +19,21 @@
 
 package org.apache.cayenne.access;
 
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.cayenne.DataObject;
 import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.Persistent;
 import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.cache.QueryCache;
-import org.apache.cayenne.query.InvalidateListCacheQuery;
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.util.GenericResponse;
+import org.apache.cayenne.query.RefreshQuery;
 import org.apache.cayenne.util.ListResponse;
 import org.apache.cayenne.util.ObjectContextQueryAction;
 
@@ -53,7 +57,7 @@
         if (interceptPaginatedQuery() != DONE) {
             if (interceptOIDQuery() != DONE) {
                 if (interceptRelationshipQuery() != DONE) {
-                    if (interceptInvalidateQuery() != DONE) {
+                    if (interceptRefreshQuery() != DONE) {
                         if (interceptLocalCache() != DONE) {
                             runQuery();
                         }
@@ -136,31 +140,66 @@
         return DONE;
     }
 
-    private boolean interceptInvalidateQuery() {
-        if (query instanceof InvalidateListCacheQuery) {
-            InvalidateListCacheQuery invalidateQuery = 
(InvalidateListCacheQuery) query;
-
-            QueryCache queryCache = ((DataContext) 
actingContext).getQueryCache();
+    private boolean interceptRefreshQuery() {
+        if (query instanceof RefreshQuery) {
+            RefreshQuery refreshQuery = (RefreshQuery) query;
+
+            DataContext context = (DataContext) actingContext;
+
+            // handle three separate scenarious, but do not combine them as it 
will be
+            // unclear how to handle cascading behavior
+
+            // 1. invalidate object collection
+            Collection objects = refreshQuery.getObjects();
+            if (objects != null && !objects.isEmpty()) {
+
+                Map diffMap = context.getObjectStore().getChangesByObjectId();
+
+                Iterator it = objects.iterator();
+                while (it.hasNext()) {
+                    Persistent object = (Persistent) it.next();
+
+                    // we don't care about NEW objects,
+                    // but we still do care about HOLLOW, since snapshot might 
still be
+                    // present
+                    if (object.getPersistenceState() == PersistenceState.NEW) {
+                        continue;
+                    }
 
-            if (invalidateQuery.getQueryNameKey() != null) {
-                queryCache.remove(invalidateQuery.getQueryNameKey());
-            }
+                    object.setPersistenceState(PersistenceState.HOLLOW);
 
-            String[] groupKeys = invalidateQuery.getGroupKeys();
-            if (groupKeys != null && groupKeys.length > 0) {
-                for (int i = 0; i < groupKeys.length; i++) {
-                    queryCache.removeGroup(groupKeys[i]);
+                    // remove cached changes
+                    diffMap.remove(object.getObjectId());
                 }
-            }
 
-            if (invalidateQuery.isCascade()) {
+                // cascade
                 return !DONE;
             }
-            else {
-                GenericResponse response = new GenericResponse();
-                response.addUpdateCount(1);
-                this.response = response;
+            // 2. refresh query - have to do it eagerly to refresh the objects 
involved
+            else if (refreshQuery.getQuery() != null) {
+                Query cachedQuery = refreshQuery.getQuery();
+
+                String cacheKey = cachedQuery
+                        .getMetaData(context.getEntityResolver())
+                        .getCacheKey();
+                context.getQueryCache().remove(cacheKey);
+
+                this.response = context.performGenericQuery(cachedQuery);
+
+                // do not cascade to avoid running query twice
                 return DONE;
+            }
+            // 3. refresh groups...
+            else if (refreshQuery.getGroupKeys() != null
+                    && refreshQuery.getGroupKeys().length > 0) {
+
+                String[] groups = refreshQuery.getGroupKeys();
+                for (int i = 0; i < groups.length; i++) {
+                    context.getQueryCache().removeGroup(groups[i]);
+                }
+
+                // cascade group invalidation
+                return !DONE;
             }
         }
 

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
 Mon Aug 21 02:16:42 2006
@@ -32,19 +32,20 @@
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.Persistent;
 import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.query.InvalidateListCacheQuery;
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.query.PrefetchSelectQuery;
 import org.apache.cayenne.query.PrefetchTreeNode;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.QueryMetadata;
 import org.apache.cayenne.query.QueryRouter;
+import org.apache.cayenne.query.RefreshQuery;
 import org.apache.cayenne.query.RelationshipQuery;
 import org.apache.cayenne.util.GenericResponse;
 import org.apache.cayenne.util.ListResponse;
@@ -106,7 +107,7 @@
         // run chain...
         if (interceptOIDQuery() != DONE) {
             if (interceptRelationshipQuery() != DONE) {
-                if (interceptInvalidateQuery() != DONE) {
+                if (interceptRefreshQuery() != DONE) {
                     if (interceptSharedCache() != DONE) {
                         runQueryInTransaction();
                     }
@@ -237,32 +238,63 @@
     /**
      * @since 3.0
      */
-    private boolean interceptInvalidateQuery() {
-        if(domain.getQueryCacheInternal() == null) {
-            return !DONE;
-        }
-        
-        if (query instanceof InvalidateListCacheQuery) {
-            InvalidateListCacheQuery invalidateQuery = 
(InvalidateListCacheQuery) query;
+    private boolean interceptRefreshQuery() {
 
-            QueryCache queryCache = domain.getQueryCache();
+        if (query instanceof RefreshQuery) {
+            RefreshQuery refreshQuery = (RefreshQuery) query;
 
-            if (invalidateQuery.getQueryNameKey() != null) {
-                queryCache.remove(invalidateQuery.getQueryNameKey());
-            }
+            Collection objects = refreshQuery.getObjects();
+            if (objects != null && !objects.isEmpty()) {
+
+                Collection ids = new ArrayList(objects.size());
+                Iterator it = objects.iterator();
+                while (it.hasNext()) {
+                    Persistent object = (Persistent) it.next();
+                    ids.add(object.getObjectId());
+                }
 
-            String[] groupKeys = invalidateQuery.getGroupKeys();
-            if (groupKeys != null && groupKeys.length > 0) {
-                for (int i = 0; i < groupKeys.length; i++) {
-                    queryCache.removeGroup(groupKeys[i]);
+                if (domain.getSharedSnapshotCache() != null) {
+                    // send an event for removed snapshots
+                    domain.getSharedSnapshotCache().processSnapshotChanges(
+                            context.getObjectStore(),
+                            Collections.EMPTY_MAP,
+                            Collections.EMPTY_LIST,
+                            ids,
+                            Collections.EMPTY_LIST);
                 }
+
+                GenericResponse response = new GenericResponse();
+                response.addUpdateCount(1);
+                this.response = response;
+                return DONE;
             }
+            // 2. refresh query - this shouldn't normally happen as child 
datacontext
+            // usually does a cascading refresh
+            else if (refreshQuery.getQuery() != null) {
+                Query cachedQuery = refreshQuery.getQuery();
+
+                String cacheKey = cachedQuery
+                        .getMetaData(context.getEntityResolver())
+                        .getCacheKey();
+                context.getQueryCache().remove(cacheKey);
 
-            // ignore 'cascade' setting - we are at the bottom of the stack 
already...
-            GenericResponse response = new GenericResponse();
-            response.addUpdateCount(1);
-            this.response = response;
-            return DONE;
+                this.response = domain.onQuery(context, cachedQuery);
+                return DONE;
+            }
+            // 3. refresh groups...
+            else if (refreshQuery.getGroupKeys() != null
+                    && refreshQuery.getGroupKeys().length > 0) {
+
+                String[] groups = refreshQuery.getGroupKeys();
+                for (int i = 0; i < groups.length; i++) {
+                    domain.getQueryCache().removeGroup(groups[i]);
+                }
+
+                GenericResponse response = new GenericResponse();
+                response.addUpdateCount(1);
+                this.response = response;
+                return DONE;
+            }
         }
 
         return !DONE;
@@ -286,7 +318,7 @@
         }
 
         QueryCache queryCache = domain.getQueryCache();
-        
+
         if (cache) {
             List cachedRows = queryCache.get(metadata);
 

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/ObjectStore.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/ObjectStore.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/ObjectStore.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/access/ObjectStore.java
 Mon Aug 21 02:16:42 2006
@@ -52,6 +52,7 @@
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.query.PrefetchTreeNode;
 import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.query.RefreshQuery;
 
 /**
  * ObjectStore stores objects using their ObjectId as a key. It works as a 
dedicated
@@ -295,44 +296,12 @@
     /**
      * Invalidates a collection of DataObjects. Changes objects state to 
HOLLOW.
      * 
-     * @see #objectsUnregistered(Collection)
+     * @deprecated since 3.0, use [EMAIL PROTECTED] 
DataContext#invalidateObjects(Collection)} or
+     *             [EMAIL PROTECTED] RefreshQuery}.
      */
     public synchronized void objectsInvalidated(Collection objects) {
-        if (objects.isEmpty()) {
-            return;
-        }
-
-        Collection ids = new ArrayList(objects.size());
-        Iterator it = objects.iterator();
-        while (it.hasNext()) {
-            Persistent object = (Persistent) it.next();
-
-            // we don't care about NEW objects,
-            // but we still do care about HOLLOW, since snapshot might still be
-            // present
-            if (object.getPersistenceState() == PersistenceState.NEW) {
-                continue;
-            }
-
-            object.setPersistenceState(PersistenceState.HOLLOW);
-
-            // remove cached changes
-            changes.remove(object.getObjectId());
-
-            // remember the id
-            ids.add(object.getObjectId());
-        }
-
-        // TODO, andrus 3/28/2006 - DRC is null in nested contexts... implement
-        // propagation of invalidate operation through the stack
-        if (getDataRowCache() != null) {
-            // send an event for removed snapshots
-            getDataRowCache().processSnapshotChanges(
-                    this,
-                    Collections.EMPTY_MAP,
-                    Collections.EMPTY_LIST,
-                    ids,
-                    Collections.EMPTY_LIST);
+        if(context != null) {
+            context.invalidateObjects(objects);
         }
     }
 
@@ -596,13 +565,12 @@
      * shared cache associated with the underlying DataRowStore.
      * 
      * @since 1.1
-     * 
      * @deprecated since 3.0. See [EMAIL PROTECTED] 
DataContext#getQueryCache()}.
      */
     public synchronized List getCachedQueryResult(String name) {
         return context != null && context.queryCache != null ? 
context.queryCache
                 .get(new CacheQueryMetadata(name)) : null;
-    }  
+    }
 
     /**
      * Caches a list of query results.
@@ -1148,7 +1116,7 @@
             throw new UnsupportedOperationException();
         }
     }
-    
+
     final class CacheQueryMetadata implements QueryMetadata {
 
         private String cacheKey;
@@ -1160,7 +1128,7 @@
         public String getCacheKey() {
             return cacheKey;
         }
-        
+
         public String[] getCacheGroups() {
             return null;
         }

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/query/RefreshQuery.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/query/RefreshQuery.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/query/RefreshQuery.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/main/java/org/apache/cayenne/query/RefreshQuery.java
 Mon Aug 21 02:16:42 2006
@@ -91,7 +91,50 @@
         return objects;
     }
 
+    /**
+     * Returns an internal query, overriding cache policy to force a refresh. 
Returns null
+     * if no query was set.
+     */
     public Query getQuery() {
-        return query;
+
+        if (query == null) {
+            return null;
+        }
+
+        return new Query() {
+
+            public SQLAction createSQLAction(SQLActionVisitor visitor) {
+                throw new CayenneRuntimeException("Unsupported");
+            }
+
+            public QueryMetadata getMetaData(EntityResolver resolver) {
+                QueryMetadata md = query.getMetaData(resolver);
+
+                QueryMetadataWrapper wrappedMd = new QueryMetadataWrapper(md);
+                if (QueryMetadata.LOCAL_CACHE.equals(md.getCachePolicy())) {
+                    wrappedMd.override(
+                            QueryMetadata.CACHE_POLICY_PROPERTY,
+                            QueryMetadata.LOCAL_CACHE_REFRESH);
+                }
+                else if 
(QueryMetadata.SHARED_CACHE.equals(md.getCachePolicy())) {
+                    wrappedMd.override(
+                            QueryMetadata.CACHE_POLICY_PROPERTY,
+                            QueryMetadata.SHARED_CACHE_REFRESH);
+                }
+
+                return wrappedMd;
+            }
+
+            public String getName() {
+                return query.getName();
+            }
+
+            public void route(
+                    QueryRouter router,
+                    EntityResolver resolver,
+                    Query substitutedQuery) {
+                query.route(router, resolver, this);
+            }
+        };
     }
 }

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/DataContextTst.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/DataContextTst.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/DataContextTst.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/DataContextTst.java
 Mon Aug 21 02:16:42 2006
@@ -21,6 +21,8 @@
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -30,6 +32,7 @@
 import org.apache.art.Exhibit;
 import org.apache.art.Painting;
 import org.apache.art.ROArtist;
+import org.apache.cayenne.DataObject;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.Fault;
 import org.apache.cayenne.ObjectId;
@@ -544,5 +547,27 @@
         artist.setArtistName("Something different");
         assertTrue(context.hasChanges());
     }
-
+    
+    public void testInvalidateObjects() throws Exception {
+        DataContext context = createDataContext();
+
+        DataRow row = new DataRow(10);
+        row.put("ARTIST_ID", new Integer(1));
+        row.put("ARTIST_NAME", "ArtistXYZ");
+        row.put("DATE_OF_BIRTH", new Date());
+        DataObject object = context.objectFromDataRow(Artist.class, row, 
false);
+        ObjectId oid = object.getObjectId();
+
+        // insert object into the ObjectStore
+        context.getObjectStore().recordObjectCreated(object);
+
+        assertSame(object, context.getObjectStore().getNode(oid));
+        assertNotNull(context.getObjectStore().getCachedSnapshot(oid));
+
+        context.invalidateObjects(Collections.singletonList(object));
+
+        assertSame(oid, object.getObjectId());
+        assertNull(context.getObjectStore().getCachedSnapshot(oid));
+        assertSame(object, context.getObjectStore().getNode(oid));
+    }
 }

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/ObjectStoreTst.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/ObjectStoreTst.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/ObjectStoreTst.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/ObjectStoreTst.java
 Mon Aug 21 02:16:42 2006
@@ -17,7 +17,6 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.access;
 
 import java.util.ArrayList;
@@ -98,29 +97,6 @@
         assertSame(freshResult, 
context.getObjectStore().getCachedQueryResult("result"));
     }
 
-    public void testObjectsInvalidated() throws Exception {
-        DataContext context = createDataContext();
-
-        DataRow row = new DataRow(10);
-        row.put("ARTIST_ID", new Integer(1));
-        row.put("ARTIST_NAME", "ArtistXYZ");
-        row.put("DATE_OF_BIRTH", new Date());
-        DataObject object = context.objectFromDataRow(Artist.class, row, 
false);
-        ObjectId oid = object.getObjectId();
-
-        // insert object into the ObjectStore
-        context.getObjectStore().recordObjectCreated(object);
-
-        assertSame(object, context.getObjectStore().getNode(oid));
-        assertNotNull(context.getObjectStore().getCachedSnapshot(oid));
-
-        
context.getObjectStore().objectsInvalidated(Collections.singletonList(object));
-
-        assertSame(oid, object.getObjectId());
-        assertNull(context.getObjectStore().getCachedSnapshot(oid));
-        assertSame(object, context.getObjectStore().getNode(oid));
-    }
-
     public void testObjectsUnregistered() throws Exception {
         DataContext context = createDataContext();
 
@@ -144,50 +120,52 @@
         // in the future this may not be the case
         assertNull(context.getObjectStore().getCachedSnapshot(oid));
     }
-    
+
     public void testUnregisterThenRegister() throws Exception {
         DataContext context = createDataContext();
-        
+
         // Create a gallery.
         Gallery g = (Gallery) 
context.createAndRegisterNewObject(Gallery.class);
         g.setGalleryName("Test Gallery");
-        
+
         // Create an artist in the same context.
         Artist a = (Artist) context.createAndRegisterNewObject(Artist.class);
         a.setArtistName("Test Artist");
-        
+
         // Create a painting in the same context.
         Painting p = (Painting) 
context.createAndRegisterNewObject(Painting.class);
         p.setPaintingTitle("Test Painting");
-        
+
         // Set the painting's gallery.
         p.setToGallery(g);
         assertEquals(g, p.getToGallery());
-        
+
         // Unregister the painting from the context.
         context.unregisterObjects(Collections.singletonList(p));
-        
+
         // Make sure that even though the painting has been removed from the 
context's
         // object graph that the reference to the gallery is the same.
         assertEquals(g, p.getToGallery());
-        
-        // Now, set the relationship between "p" & "a."  Since "p" is not 
registered with a
+
+        // Now, set the relationship between "p" & "a." Since "p" is not 
registered with a
         // context, but "a" is, "p" should be auto-registered with the context 
of "a."
         p.setToArtist(a);
-        
+
         // Now commit the gallery, artist, & painting.
         context.commitChanges();
-        
+
         // Check one last time that the painting's gallery is set to what we 
expect.
         assertEquals(g, p.getToGallery());
-        
-        // Now, retrieve the same painting from the DB.  Note that the gallery 
relationship
-        // is null even though according to our painting, that should not be 
the case; a NULL
+
+        // Now, retrieve the same painting from the DB. Note that the gallery 
relationship
+        // is null even though according to our painting, that should not be 
the case; a
+        // NULL
         // value has been recorded to the DB for the painting's gallery_id 
field.
         //
         // The full object graph is not being re-registered during 
auto-registration
         // with the context.
-        Painting newP = (Painting) 
DataObjectUtils.objectForPK(createDataContext(), p.getObjectId());
+        Painting newP = (Painting) 
DataObjectUtils.objectForPK(createDataContext(), p
+                .getObjectId());
         assertNotNull(newP.getToGallery());
     }
 }

Added: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/RefreshQueryInContextTst.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/RefreshQueryInContextTst.java?rev=433202&view=auto
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/RefreshQueryInContextTst.java
 (added)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/access/RefreshQueryInContextTst.java
 Mon Aug 21 02:16:42 2006
@@ -0,0 +1,351 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+import java.util.List;
+
+import org.apache.art.Artist;
+import org.apache.art.Painting;
+import org.apache.cayenne.DataObjectUtils;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.query.RefreshQuery;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.unit.CayenneTestCase;
+
+public class RefreshQueryInContextTst extends CayenneTestCase {
+
+    public void testRefreshCollection() throws Exception {
+        deleteTestData();
+        createTestData("testRefreshCollection");
+
+        DataContext context = createDataContext();
+
+        SelectQuery q = new SelectQuery(Artist.class);
+        q.addOrdering("db:ARTIST_ID", true);
+        List artists = context.performQuery(q);
+
+        Artist a1 = (Artist) artists.get(0);
+        Artist a2 = (Artist) artists.get(1);
+
+        assertEquals(2, a1.getPaintingArray().size());
+        assertEquals(0, a2.getPaintingArray().size());
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(a1.getObjectId()));
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(a2.getObjectId()));
+
+        RefreshQuery refresh = new RefreshQuery(artists);
+        context.performQuery(refresh);
+
+        assertNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(a1.getObjectId()));
+        assertNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(a2.getObjectId()));
+
+        assertEquals(PersistenceState.HOLLOW, a1.getPersistenceState());
+        assertEquals(PersistenceState.HOLLOW, a2.getPersistenceState());
+
+        assertTrue(((ValueHolder) 
a1.readProperty(Artist.PAINTING_ARRAY_PROPERTY))
+                .isFault());
+        assertTrue(((ValueHolder) 
a2.readProperty(Artist.PAINTING_ARRAY_PROPERTY))
+                .isFault());
+    }
+
+    public void testRefreshCollectionToOne() throws Exception {
+        deleteTestData();
+        createTestData("testRefreshCollection");
+
+        DataContext context = createDataContext();
+
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.addOrdering("db:PAINTING_ID", true);
+        List paints = context.performQuery(q);
+
+        Painting p1 = (Painting) paints.get(0);
+        Painting p2 = (Painting) paints.get(1);
+
+        Artist a1 = p1.getToArtist();
+        assertSame(a1, p2.getToArtist());
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        createTestData("testRefreshCollectionToOneUpdate");
+
+        RefreshQuery refresh = new RefreshQuery(paints);
+        context.performQuery(refresh);
+
+        assertNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+        assertNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        assertEquals(PersistenceState.HOLLOW, p1.getPersistenceState());
+        assertEquals(PersistenceState.HOLLOW, p2.getPersistenceState());
+
+        assertNotSame(a1, p1.getToArtist());
+        assertNotSame(a1, p2.getToArtist());
+        assertEquals("b", p1.getToArtist().getArtistName());
+    }
+
+    public void testRefreshSingleObject() throws Exception {
+        deleteTestData();
+        createTestData("testRefreshCollection");
+
+        DataContext context = createDataContext();
+
+        SelectQuery q = new SelectQuery(Artist.class);
+        q.addOrdering("db:ARTIST_ID", true);
+        List artists = context.performQuery(q);
+
+        Artist a1 = (Artist) artists.get(0);
+
+        assertEquals(2, a1.getPaintingArray().size());
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(a1.getObjectId()));
+
+        RefreshQuery refresh = new RefreshQuery(a1);
+        context.performQuery(refresh);
+
+        assertNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(a1.getObjectId()));
+
+        assertEquals(PersistenceState.HOLLOW, a1.getPersistenceState());
+
+        assertTrue(((ValueHolder) 
a1.readProperty(Artist.PAINTING_ARRAY_PROPERTY))
+                .isFault());
+    }
+
+    public void testRefreshQueryResultsLocalCache() throws Exception {
+        deleteTestData();
+        createTestData("testRefreshCollection");
+
+        DataContext context = createDataContext();
+
+        Expression qual = ExpressionFactory.matchExp(
+                Painting.PAINTING_TITLE_PROPERTY,
+                "P2");
+        SelectQuery q = new SelectQuery(Painting.class, qual);
+        q.addOrdering("db:PAINTING_ID", true);
+        q.setCachePolicy(QueryMetadata.LOCAL_CACHE);
+        q.setCacheGroups(new String[] {
+            "X"
+        });
+        List paints = context.performQuery(q);
+
+        // fetch P1 separately from cached query
+        Painting p1 = (Painting) DataObjectUtils.objectForPK(
+                context,
+                Painting.class,
+                33001);
+
+        Painting p2 = (Painting) paints.get(0);
+        Artist a1 = p2.getToArtist();
+        assertSame(a1, p1.getToArtist());
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        createTestData("testRefreshCollectionToOneUpdate");
+
+        RefreshQuery refresh = new RefreshQuery(q);
+        context.performQuery(refresh);
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+
+        // probably refreshed eagerly
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        assertEquals(PersistenceState.COMMITTED, p1.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, p2.getPersistenceState());
+
+        assertSame(a1, p1.getToArtist());
+        assertNotSame(a1, p2.getToArtist());
+        assertEquals("c", p1.getToArtist().getArtistName());
+        assertEquals("b", p2.getToArtist().getArtistName());
+    }
+    
+    public void testRefreshQueryResultsSharedCache() throws Exception {
+        deleteTestData();
+        createTestData("testRefreshCollection");
+
+        DataContext context = createDataContext();
+
+        Expression qual = ExpressionFactory.matchExp(
+                Painting.PAINTING_TITLE_PROPERTY,
+                "P2");
+        SelectQuery q = new SelectQuery(Painting.class, qual);
+        q.addOrdering("db:PAINTING_ID", true);
+        q.setCachePolicy(QueryMetadata.SHARED_CACHE);
+        q.setCacheGroups(new String[] {
+            "X"
+        });
+        List paints = context.performQuery(q);
+
+        // fetch P1 separately from cached query
+        Painting p1 = (Painting) DataObjectUtils.objectForPK(
+                context,
+                Painting.class,
+                33001);
+
+        Painting p2 = (Painting) paints.get(0);
+        Artist a1 = p2.getToArtist();
+        assertSame(a1, p1.getToArtist());
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        createTestData("testRefreshCollectionToOneUpdate");
+
+        RefreshQuery refresh = new RefreshQuery(q);
+        context.performQuery(refresh);
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+
+        // probably refreshed eagerly
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        assertEquals(PersistenceState.COMMITTED, p1.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, p2.getPersistenceState());
+
+        assertSame(a1, p1.getToArtist());
+        assertNotSame(a1, p2.getToArtist());
+        assertEquals("c", p1.getToArtist().getArtistName());
+        assertEquals("b", p2.getToArtist().getArtistName());
+    }
+
+    public void testRefreshQueryResultGroupLocal() throws Exception {
+        deleteTestData();
+        createTestData("testRefreshCollection");
+
+        DataContext context = createDataContext();
+
+        Expression qual = ExpressionFactory.matchExp(
+                Painting.PAINTING_TITLE_PROPERTY,
+                "P2");
+        SelectQuery q = new SelectQuery(Painting.class, qual);
+        q.addOrdering("db:PAINTING_ID", true);
+        q.setCachePolicy(QueryMetadata.LOCAL_CACHE);
+        q.setCacheGroups(new String[] {
+            "X"
+        });
+        List paints = context.performQuery(q);
+
+        // fetch P1 separately from cached query
+        Painting p1 = (Painting) DataObjectUtils.objectForPK(
+                context,
+                Painting.class,
+                33001);
+
+        Painting p2 = (Painting) paints.get(0);
+        Artist a1 = p2.getToArtist();
+        assertSame(a1, p1.getToArtist());
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p1.getObjectId()));
+
+        assertNotNull(context
+                .getParentDataDomain()
+                .getSharedSnapshotCache()
+                .getCachedSnapshot(p2.getObjectId()));
+
+        createTestData("testRefreshCollectionToOneUpdate");
+
+        // results are served from cache and therefore are not refreshed
+        context.performQuery(q);
+        assertSame(a1, p1.getToArtist());
+        assertSame(a1, p2.getToArtist());
+        assertEquals("c", p1.getToArtist().getArtistName());
+        assertEquals("c", p2.getToArtist().getArtistName());
+
+        RefreshQuery refresh = new RefreshQuery(new String[] {
+            "X"
+        });
+
+        // this should invalidate results for the next query run
+        context.performQuery(refresh);
+
+        // this should force a refresh
+        context.performQuery(q);
+
+        assertEquals(PersistenceState.COMMITTED, p1.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, p2.getPersistenceState());
+
+        assertSame(a1, p1.getToArtist());
+        assertNotSame(a1, p2.getToArtist());
+        assertEquals("c", p1.getToArtist().getArtistName());
+        assertEquals("b", p2.getToArtist().getArtistName());
+    }
+}

Modified: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/query/RefreshQueryTst.java
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/query/RefreshQueryTst.java?rev=433202&r1=433201&r2=433202&view=diff
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/query/RefreshQueryTst.java
 (original)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/java/org/apache/cayenne/query/RefreshQueryTst.java
 Mon Aug 21 02:16:42 2006
@@ -68,7 +68,8 @@
 
         RefreshQuery q = new RefreshQuery(query);
         assertNull(q.getObjects());
-        assertEquals(query, q.getQuery());
+        assertNotNull(q.getQuery());
+        assertNotSame("query must be wrapped", query, q.getQuery());
         assertNull(q.getGroupKeys());
         assertFalse(q.isRefreshAll());
     }
@@ -83,7 +84,7 @@
         assertNull(q.getQuery());
         assertSame(groupKeys, q.getGroupKeys());
     }
-    
+
     public void testSerializabilityWithHessian() throws Exception {
         RefreshQuery o = new RefreshQuery();
         Object clone = HessianUtil.cloneViaClientServerSerialization(

Added: 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/resources/dml/access.RefreshQueryInContextTst.xml
URL: 
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/resources/dml/access.RefreshQueryInContextTst.xml?rev=433202&view=auto
==============================================================================
--- 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/resources/dml/access.RefreshQueryInContextTst.xml
 (added)
+++ 
incubator/cayenne/main/trunk/core/cayenne-jdk1.4-core/src/test/resources/dml/access.RefreshQueryInContextTst.xml
 Mon Aug 21 02:16:42 2006
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd";>
+
+<beans default-lazy-init="true">       
+       <!-- ======================================= -->
+       <!-- Named Queries -->
+       <!-- ======================================= -->
+       
+       <!-- ARTIST -->
+       <bean id="A1" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+               <constructor-arg 
type="java.lang.Class"><value>org.apache.art.Artist</value></constructor-arg>
+               <constructor-arg><value>
+               insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33001, 'c')
+               </value></constructor-arg>
+       </bean>
+       
+       <bean id="A2" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+               <constructor-arg 
type="java.lang.Class"><value>org.apache.art.Artist</value></constructor-arg>
+               <constructor-arg><value>
+               insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33002, 'b')
+               </value></constructor-arg>
+       </bean>
+       
+       <bean id="P11" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+               <constructor-arg 
type="java.lang.Class"><value>org.apache.art.Painting</value></constructor-arg>
+               <constructor-arg><value>
+               INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, 
ESTIMATED_PRICE) VALUES (33001, 'P1', 33001, 3000)
+               </value></constructor-arg>
+       </bean>
+       
+       <bean id="P12" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+               <constructor-arg 
type="java.lang.Class"><value>org.apache.art.Painting</value></constructor-arg>
+               <constructor-arg><value>
+               INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, 
ESTIMATED_PRICE) VALUES (33002, 'P2', 33001, 4000)
+               </value></constructor-arg>
+       </bean>
+       
+       <bean id="PU1" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+               <constructor-arg 
type="java.lang.Class"><value>org.apache.art.Painting</value></constructor-arg>
+               <constructor-arg><value>
+               UPDATE PAINTING set ARTIST_ID = 33002;
+               </value></constructor-arg>
+       </bean>
+       
+       <!-- ======================================= -->
+       <!-- Data Sets -->
+       <!-- ======================================= -->        
+       
+       <bean id="testRefreshCollection" class="java.util.ArrayList">
+               <constructor-arg>
+                       <list>
+                               <ref bean="A1"/>
+                               <ref bean="A2"/>
+                               <ref bean="P11"/>
+                               <ref bean="P12"/>
+                       </list>
+               </constructor-arg>
+       </bean>
+       
+       <bean id="testRefreshCollectionToOneUpdate" class="java.util.ArrayList">
+               <constructor-arg>
+                       <list>
+                               <ref bean="PU1"/>
+                       </list>
+               </constructor-arg>
+       </bean>
+</beans>
\ No newline at end of file


Reply via email to