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