You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2008/02/15 10:20:40 UTC
svn commit: r627979 [7/39] - in /openjpa/trunk:
openjpa-lib/src/test/java/org/apache/openjpa/lib/test/
openjpa-persistence-jdbc/ openjpa-persistence-jdbc/src/test/java/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/
openjpa-pers...
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,1591 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.AppIdCacheObject;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild2;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectBChild1;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectC;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectD;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectF;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectG;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectH;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectInterface;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
+import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+import org.apache.openjpa.datacache.ConcurrentDataCache;
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.DelegatingDataCache;
+import org.apache.openjpa.datacache.QueryCache;
+import org.apache.openjpa.datacache.TypesChangedEvent;
+import org.apache.openjpa.datacache.DataCacheManager;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCData;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.util.CacheMap;
+import org.apache.openjpa.util.Id;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.ProxyDate;
+
+/**
+ * ### should add 1..1 relation test ### app id compound key test
+ */
+public abstract class CacheTest extends AbstractTestCase {
+
+ private static String ORIG_NAME = "origName";
+
+ private static String NEW_NAME = "newName";
+
+ private static int ORIG_AGE = 30;
+
+ private static String ORIG_PARENT_NAME = "origParentName";
+
+ private static int ORIG_PARENT_AGE = 31;
+
+ private OpenJPAEntityManagerFactory timeoutFactory = null;
+
+ private OpenJPAEntityManagerFactory factory = null;
+
+ private OpenJPAEntityManagerFactory factory2 = null;
+
+ private MetaDataRepository repos;
+
+ private Object oid;
+
+ private Object parentOid;
+
+ private Object oidwithclass;
+
+ private OpenJPAEntityManager em;
+
+ private CacheObjectA a;
+
+ public CacheTest(String test) {
+ super(test, "datacachecactusapp");
+ }
+
+ public void clear() throws Exception {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ Class[] toDelete = new Class[]{ CacheObjectA.class,
+ CacheObjectB.class, CacheObjectC.class, CacheObjectD.class,
+ CacheObjectE.class, CacheObjectJ.class,
+ AppIdCacheObject.class, };
+ for (int i = 0; i < toDelete.length; i++) {
+ startTx(em);
+ Extent e = em.createExtent(toDelete[i], true);
+ Iterator it = e.iterator();
+ while (it.hasNext()) {
+ em.remove(it.next());
+ }
+ endTx(em);
+ }
+ }
+ catch (OpenJPAException jpae) {
+ Throwable[] ts = jpae.getNestedThrowables();
+ for (int i = 0; ts != null && i < ts.length; i++) {
+ ts[i].printStackTrace();
+ }
+// jpae.printStackTrace();
+
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ /**
+ * Return a string array of extra configuration options for the specified
+ * cache.
+ */
+ protected abstract String[] getConfs();
+
+ /**
+ * Return a string array of extra configuration options for a second cache.
+ */
+ protected abstract String[] getConfs2();
+
+ /**
+ * Return true if this cache is a coherent one (one where changes in one
+ * cache are immediately visible elsewhere); otherwise returns false. In the
+ * context of this test class, coherence is a single-JVM thing only.
+ */
+ protected boolean isCacheCoherent() {
+ return false;
+ }
+
+ public void setUp() throws Exception {
+
+ String[] confs = getConfs();
+ for (int i = 0; i < confs.length; i = i + 2) {
+ if ("openjpa.DataCache".equals(confs[i]))
+ confs[i + 1] +=
+ ", true(Name=not-the-default-cache, CacheSize=10)";
+ }
+
+ String[] confs2 = getConfs2();
+ for (int i = 0; i < confs2.length; i = i + 2) {
+ if ("openjpa.DataCache".equals(confs2[i]))
+ confs2[i + 1] +=
+ ", true(Name=not-the-default-cache, CacheSize=10)";
+ }
+
+ Map propsMap1 = new HashMap();
+ for (int i = 0; i < confs.length; i += 2) {
+ propsMap1.put(confs[i], confs[i + 1]);
+ }
+ Map propsMap2 = new HashMap();
+ for (int i = 0; i < confs2.length; i += 2) {
+ propsMap2.put(confs2[i], confs2[i + 1]);
+ }
+
+ factory = (OpenJPAEntityManagerFactory) getEmf(propsMap1);
+ factory2 = (OpenJPAEntityManagerFactory) getEmf(propsMap2);
+
+ repos = JPAFacadeHelper.toBrokerFactory(factory).getConfiguration()
+ .getMetaDataRepositoryInstance();
+
+ String[] biggerConfs = new String[confs.length + 2];
+ System.arraycopy(confs, 0, biggerConfs, 0, confs.length);
+ biggerConfs[biggerConfs.length - 2] = "openjpa.DataCacheTimeout";
+ biggerConfs[biggerConfs.length - 1] = "1000";
+ Map propsMap3 = new HashMap();
+ for (int i = 0; i < biggerConfs.length; i += 2) {
+ propsMap3.put(biggerConfs[i], biggerConfs[i + 1]);
+ }
+ timeoutFactory = (OpenJPAEntityManagerFactory) getEmf(propsMap3);
+
+ clear();
+
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+
+ CacheObjectA a;
+ CacheObjectA aparent;
+ try {
+ // we can't specify this for UserTransaction
+ /*
+ * pm.currentTransaction().setNontransactionalRead(true);
+ * pm.currentTransaction().setOptimistic(true);
+ */
+
+// em.setNontransactionalRead(true);
+// em.setOptimistic(true);
+
+ a = new CacheObjectA(ORIG_NAME, ORIG_AGE);
+ aparent = new CacheObjectA(ORIG_PARENT_NAME, ORIG_PARENT_AGE);
+ a.setRelatedObject(aparent);
+ LinkedList children = new LinkedList();
+ children.add(a);
+ aparent.setRelatedCollection(children);
+
+ startTx(em);
+ em.persist(a);
+ em.persist(aparent);
+ oid = em.getObjectId(a);
+ oidwithclass = new Id(CacheObjectA.class, oid.toString());
+ parentOid = em.getObjectId(aparent);
+ endTx(em);
+ }
+ finally {
+ endEm(em);
+ }
+
+ // load an object in a separate pm before the update
+ // happens. This should not change, else we're in
+ // violation of the spec.
+ this.em = factory.createEntityManager();
+ startTx(this.em);
+ try {
+ // OpenJPAEntityManager openEm=(OpenJPAEntityManager) this.em;
+ this.a = (CacheObjectA) this.em.find(CacheObjectA.class, oid);
+
+ // load the parent for testCollections().
+ CacheObjectA rel = this.a.getRelatedObject();
+ rel.getRelatedCollection();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ finally {
+ endTx(this.em);
+ // endEm(this.em);
+ }
+
+ em = factory.createEntityManager();
+ try {
+ startTx(em);
+ a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+ a.setName(NEW_NAME);
+
+ aparent = (CacheObjectA) em.find(CacheObjectA.class, parentOid);
+
+ CacheObjectA a2 = new CacheObjectA(ORIG_NAME, ORIG_AGE);
+ a2.setRelatedObject(aparent);
+ aparent.getRelatedCollection().add(a2);
+ em.persist(a2);
+ endTx(em);
+
+ assertNew(a);
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ public void tearDown() throws Exception {
+ endEm(em);
+
+ try {
+ factory.close();
+ }
+ catch (Exception e) {
+ }
+ try {
+ factory2.close();
+ }
+ catch (Exception e) {
+ }
+ super.tearDown();
+
+ factory = null;
+ factory2 = null;
+ timeoutFactory = null;
+ oid = null;
+ parentOid = null;
+ em = null;
+ a = null;
+ }
+
+ public void testDeletedOneToOneRelations() throws Exception {
+ EntityManager em = factory.createEntityManager();
+ try {
+ startTx(em);
+ CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+ assertNotNull(a.getRelatedObject());
+ em.remove(a.getRelatedObject());
+ endTx(em);
+ }
+ finally {
+ endEm(em);
+ }
+
+ EntityManager em2 = factory.createEntityManager();
+ try {
+ CacheObjectA a2 = (CacheObjectA) em2.find(CacheObjectA.class, oid);
+ assertNull(a2.getRelatedObject());
+ }
+ finally {
+ endEm(em2);
+ }
+ }
+
+ public void testCanCacheExtension() throws Exception {
+ DataCache cache = cacheManager(factory).getSystemDataCache();
+
+ // first, test caching of newly created objects.
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ Object o;
+ Object oid;
+ try {
+ startTx(em);
+ o = new CacheObjectB("foo");
+ em.persist(o);
+ endTx(em);
+ oid = em.getObjectId(o);
+ assertNotNull(oid);
+ assertNull(cache.get(oid));
+ }
+ finally {
+ endEm(em);
+ }
+
+ // now, test caching of data loaded from the data store.
+ em = factory.createEntityManager();
+ try {
+ o = em.find(CacheObjectB.class, oid);
+ assertNotNull(o);
+ assertNull(cache.get(oid));
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ public void testGetCache() {
+ // first, test caching of newly created objects.
+ DataCache defaultCache = cacheManager(factory).getDataCache(
+ DataCache.NAME_DEFAULT, false);
+ assertNotNull(defaultCache);
+
+ DataCache cache = cacheManager(factory).getSystemDataCache();
+ assertEquals(defaultCache, cache);
+
+ ClassMetaData aMeta = repos.getMetaData(CacheObjectA.class, null, true);
+ ClassMetaData aChild1Meta = repos.getMetaData(CacheObjectAChild1.class,
+ null, true);
+ ClassMetaData aChild2Meta = repos.getMetaData(CacheObjectAChild2.class,
+ null, true);
+ ClassMetaData bMeta = repos.getMetaData(CacheObjectB.class, null, true);
+ ClassMetaData bChild1Meta = repos.getMetaData(CacheObjectBChild1.class,
+ null, true);
+ ClassMetaData cMeta = repos.getMetaData(CacheObjectC.class, null, true);
+ ClassMetaData dMeta = repos.getMetaData(CacheObjectD.class, null, true);
+ ClassMetaData eMeta = repos.getMetaData(CacheObjectE.class, null, true);
+
+ cache = aMeta.getDataCache();
+ assertEquals(defaultCache, cache);
+ System.out.println("******DataCacheName:"
+ + aChild2Meta.getDataCacheName());
+ assertNull(aChild2Meta.getDataCache());
+
+ assertNull(bMeta.getDataCache());
+
+ assertEquals(cMeta.getDataCache(), dMeta.getDataCache());
+ if (dMeta.getDataCache() instanceof ConcurrentDataCache) {
+ ConcurrentDataCache dCacheImpl =
+ (ConcurrentDataCache) dMeta.getDataCache();
+ assertEquals(10, dCacheImpl.getCacheSize());
+ }
+ assertEquals(aMeta.getDataCache(), eMeta.getDataCache());
+ }
+
+ public void testPrimitives() throws Exception {
+ // make sure that the 'a' that was found before changes
+ // were made is still valid.
+ assertOld(a);
+ em.refresh(a);
+ assertNew(a);
+ }
+
+ // FIXME Seetha Sep 25,2006
+ /*
+ * public void testCollections() throws Exception { CacheObjectA parent =
+ * (CacheObjectA) em.find(CacheObjectA.class,ORIG_PARENT_NAME);
+ * assertEquals(1, parent.getRelatedCollection().size());
+ * em.refresh(parent); assertEquals(2,
+ * parent.getRelatedCollection().size()); }
+ */
+
+ // FIXME Seetha Sep 25,2006
+ /*
+ * public void testExpiredCollections() { CacheObjectA parent =
+ * (CacheObjectA) em.find(CacheObjectA.class,ORIG_PARENT_NAME);
+ * em.refresh(parent); Collection relatedOids = new HashSet(); for (Iterator
+ * iter = parent.getRelatedCollection().iterator(); iter.hasNext();) {
+ * relatedOids.add(JDOHelper.getObjectId(iter.next())); }
+ *
+ * ClassMetaData meta = repos.getMetaData(CacheObjectA.class, null, true);
+ * DataCache cache = meta.getDataCache();
+ * // drop the related data from the cache for (Iterator iter =
+ * relatedOids.iterator(); iter.hasNext();) cache.remove(iter.next());
+ *
+ * PersistenceManager pm2 = factory.getPersistenceManager(); try {
+ * assertTrue(cache.contains(parentOid)); parent = (CacheObjectA)
+ * pm2.getObjectById(parentOid, true);
+ *
+ * try { for (Iterator iter = relatedOids.iterator(); iter.hasNext();)
+ * assertFalse(cache.contains(iter.next())); } catch (AssertionFailedError
+ * e) { bug(467, "data cache can over-eagerly load relation data"); } }
+ * finally { close(pm2); } }
+ */
+
+ public void testExpiredRelations() {
+ CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+ em.refresh(a);
+ Object relationOid = em.getObjectId(a.getRelatedObject());
+ relationOid = new Id(CacheObjectA.class, relationOid.toString());
+
+ ClassMetaData meta = repos.getMetaData(CacheObjectA.class, null, true);
+ DataCache cache = meta.getDataCache();
+
+ // drop the related data from the cache
+ cache.remove(relationOid);
+
+ OpenJPAEntityManager em2 = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ assertTrue(cache.contains(oidwithclass));
+ a = (CacheObjectA) em2.find(CacheObjectA.class, oid);
+
+ try {
+ assertFalse(cache.contains(relationOid));
+ }
+ catch (AssertionFailedError e) {
+ // bug(467, "data cache can over-eagerly load relation data");
+ e.printStackTrace();
+ }
+ }
+ finally {
+ endEm(em2);
+ }
+ }
+
+ public void testPCArrays() throws Exception {
+ OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ startTx(newEm);
+ CacheObjectA parent = (CacheObjectA) newEm.find(CacheObjectA.class,
+ parentOid);
+ CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ a.setRelatedArray(new CacheObjectA[]{ parent, a });
+ endTx(newEm);
+ }
+ finally {
+ endEm(newEm);
+ }
+
+ newEm = (OpenJPAEntityManager) factory.createEntityManager();
+ try {
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ CacheObjectA[] array = a.getRelatedArray();
+ assertEquals(2, array.length);
+ assertTrue(array[0] instanceof CacheObjectA);
+ assertTrue(array[1] instanceof CacheObjectA);
+
+ Object arrayOid = newEm.getObjectId(array[0]);
+ if (!arrayOid.equals(parentOid) && !arrayOid.equals(oid)) {
+ fail("array does not contain correct oids");
+ }
+
+ arrayOid = newEm.getObjectId(array[1]);
+ if (!arrayOid.equals(parentOid) && !arrayOid.equals(oid)) {
+ fail("array does not contain correct oids");
+ }
+ }
+ finally {
+ endEm(newEm);
+ }
+ }
+
+ public void testStringArrays() throws Exception {
+ OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ startTx(newEm);
+ CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ a.setStringArray(new String[]{ "string0", "string1", "string2" });
+ endTx(newEm);
+ }
+ finally {
+ endEm(newEm);
+ }
+
+ newEm = (OpenJPAEntityManager) factory.createEntityManager();
+ try {
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ String[] array = a.getStringArray();
+ assertEquals(3, array.length);
+ assertEquals("string0", array[0]);
+ assertEquals("string1", array[1]);
+ assertEquals("string2", array[2]);
+ }
+ finally {
+ endEm(newEm);
+ }
+ }
+
+ public void testPrimitiveArrays() throws Exception {
+ OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ startTx(newEm);
+ CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ a.setPrimitiveArray(new float[]{ 0, 1, 2 });
+ endTx(newEm);
+ }
+ finally {
+ endEm(newEm);
+ }
+
+ newEm = (OpenJPAEntityManager) factory.createEntityManager();
+ try {
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ float[] array = a.getPrimitiveArray();
+ assertEquals(3, array.length);
+ assertEquals(0.0F, array[0], 0);
+ assertEquals(1.0F, array[1], 0);
+ assertEquals(2.0f, array[2], 0);
+ }
+ finally {
+ endEm(newEm);
+ }
+ }
+
+ public void testDateArrays() throws Exception {
+ OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ CacheObjectA a;
+ Date[] dateArray;
+ try {
+ startTx(newEm);
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ dateArray = new Date[]{ new Date(), new Date(), new Date() };
+ a.setDateArray(dateArray);
+ endTx(newEm);
+ }
+ finally {
+ endEm(newEm);
+ }
+
+ newEm = (OpenJPAEntityManager) factory.createEntityManager();
+ try {
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ Date[] array = a.getDateArray();
+ if (array[0] == dateArray[0]) {
+ fail("date objects are the same");
+ }
+ }
+ finally {
+ endEm(newEm);
+ }
+ }
+
+ public void testDate() throws Exception {
+ OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ CacheObjectA a;
+ Date d;
+ try {
+ startTx(newEm);
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ d = new Date();
+ a.setDate(d);
+ endTx(newEm);
+ }
+ finally {
+ endEm(newEm);
+ }
+
+ // sleep a bit so we can ensure that the date doesn't just
+ // happen to be the same.
+ Thread.sleep(100);
+
+ newEm = (OpenJPAEntityManager) factory.createEntityManager();
+ try {
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ Date d2 = a.getDate();
+ if (d == d2) {
+ fail("date objects are the same");
+ }
+
+ assertEquals(d.getTime(), d2.getTime());
+ }
+ finally {
+ endEm(newEm);
+ }
+ }
+
+ public void testLocale() throws Exception {
+ OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ startTx(newEm);
+ CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ Locale l = Locale.getDefault();
+ a.setLocale(l);
+ endTx(newEm);
+
+ OpenJPAEntityManager newEm2 = (OpenJPAEntityManager) factory
+ .createEntityManager();
+
+ a = (CacheObjectA) newEm2.find(CacheObjectA.class, oid);
+ Locale l2 = a.getLocale();
+ // locales are immutable and final, so the different cached
+ // copies should be ==.
+ if (l != l2) {
+ fail("locale objects are not the same.");
+ }
+
+ endEm(newEm);
+ endEm(newEm2);
+ }
+
+ // ---------- Test query caching ----------
+ // * FCOs as params
+ // * multi-threaded stuff
+ // * access path stuff (see also TestQueryAccessPath)
+ // * serializability of returned lists
+ // * PM.setQueryCacheEnabled (false);
+ // * Query.setQueryCacheEnabled (false);
+ // * Pessimistic transactions
+
+ public void testBasicQuery() {
+ basicQueries(factory.createEntityManager(), Boolean.FALSE, 3, 1);
+ basicQueries(factory.createEntityManager(), Boolean.TRUE, 3, 1);
+
+ // manually notify the cache of changes
+ QueryCache cache = cacheManager(factory).getSystemQueryCache();
+
+ // test to see if modifying B causes A's query cache to be flushed
+ Set s = new HashSet();
+ s.add(CacheObjectB.class);
+ cache.onTypesChanged(new TypesChangedEvent(this, s));
+ basicQueries(factory.createEntityManager(), Boolean.TRUE, 3, 1);
+
+ // test to see if modifying A causes A's query cache to be flushed
+ s.add(CacheObjectA.class);
+ cache.onTypesChanged(new TypesChangedEvent(this, s));
+ basicQueries(factory.createEntityManager(), Boolean.FALSE, 3, 1);
+
+ // make sure that non-manual notification works
+ EntityManager em = factory.createEntityManager();
+ try {
+ startTx(em);
+ CacheObjectA a = new CacheObjectA(ORIG_NAME, ORIG_AGE);
+ em.persist(a);
+ endTx(em);
+ }
+ finally {
+ endEm(em);
+ }
+
+ basicQueries(factory.createEntityManager(), Boolean.FALSE, 4, 2);
+ }
+
+ protected void basicQueries(EntityManager em, Boolean inCache, int allSize,
+ int origSize) {
+ try {
+ long start;
+ long q1p1;
+ long q1p2;
+ long q2p1;
+ long q2p2;
+
+ Broker broker = JPAFacadeHelper.toBroker(em);
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectA.class.getSimpleName() + " a");
+ q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+ start = System.currentTimeMillis();
+ assertInCache(q, inCache);
+ List l = (List) q.execute();
+ iterate(l);
+ q1p1 = System.currentTimeMillis() - start;
+
+ assertEquals(allSize, l.size());
+
+ start = System.currentTimeMillis();
+ List l2 = (List) q.execute();
+ iterate(l2);
+ q1p2 = System.currentTimeMillis() - start;
+ assertEquals(allSize, l2.size());
+
+ q = broker.newQuery(JPQLParser.LANG_JPQL,
+ "select a.name,a.age from "
+ + CacheObjectA.class.getSimpleName()
+ + " a where a.name = :n AND a.age = :a");
+ q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+ start = System.currentTimeMillis();
+ assertInCache(q, inCache, new Object[]{ ORIG_NAME,
+ new Integer(ORIG_AGE) });
+ l = (List) q.execute(new Object[]{ ORIG_NAME,
+ new Integer(ORIG_AGE) });
+ iterate(l);
+ q2p1 = System.currentTimeMillis() - start;
+
+ assertEquals(origSize, l.size());
+
+ start = System.currentTimeMillis();
+ l2 = (List) q.execute(new Object[]{ ORIG_NAME,
+ new Integer(ORIG_AGE) });
+ iterate(l2);
+ q2p2 = System.currentTimeMillis() - start;
+
+ assertEquals(origSize, l2.size());
+ // System.out.println ("inCache: " + inCache + ";\t q1p1: " + q1p1
+ // + ";\t q1p2: " + q1p2 + ";\t q2p1: " + q2p1 + ";\t q2p2: "
+ // + q2p2);
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ public void testNonCacheableClass() {
+ Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+ try {
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectB.class.getSimpleName() + " a");
+
+ Collection c = (Collection) q.execute();
+ iterate(c);
+
+ assertInCache(q, Boolean.FALSE);
+ }
+ finally {
+ close(broker);
+ }
+ }
+
+ public void testNonCacheableAccessPath() {
+ Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+ try {
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectA.class.getSimpleName()
+ + " a where a.relatedB.str = 'foo'");
+ // "relatedB.str == 'foo'");
+ q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+
+ Collection c = (Collection) q.execute();
+ iterate(c);
+
+ assertInCache(q, Boolean.FALSE);
+ }
+ finally {
+ close(broker);
+ }
+ }
+
+ public void testNonCacheableSubclasses1() {
+ Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+ try {
+ // a query on the CacheObjectA class includes an uncacheable
+ // class; it should therefore not be cacheable.
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectA.class.getSimpleName() + " a");
+
+ Collection c = (Collection) q.execute();
+ iterate(c);
+
+ assertInCache(q, Boolean.FALSE);
+ }
+ finally {
+ close(broker);
+ }
+ }
+
+ public void testNonCacheableSubclasses2() {
+ Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+ try {
+ // a query on the CacheObjectA extent configured without
+ // subclasses does not include an uncacheable class; it should
+ // therefore be cacheable.
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "select a from "
+ + CacheObjectA.class.getSimpleName() + " a");
+ q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+
+ Collection c = (Collection) q.execute();
+ iterate(c);
+
+ assertInCache(q, Boolean.TRUE);
+ }
+ finally {
+ close(broker);
+ }
+ }
+
+ public void testCacheNames() {
+ assertCacheName(CacheObjectA.class, DataCache.NAME_DEFAULT);
+ assertCacheName(CacheObjectAChild1.class, DataCache.NAME_DEFAULT);
+ assertCacheName(CacheObjectAChild2.class, null);
+ assertCacheName(CacheObjectB.class, null);
+ assertCacheName(CacheObjectBChild1.class, null);
+ assertCacheName(CacheObjectC.class, "not-the-default-cache");
+ assertCacheName(CacheObjectD.class, "not-the-default-cache");
+ assertCacheName(CacheObjectE.class, DataCache.NAME_DEFAULT);
+ assertCacheName(CacheObjectF.class, DataCache.NAME_DEFAULT);
+ assertCacheName(CacheObjectG.class, DataCache.NAME_DEFAULT);
+ assertCacheName(CacheObjectH.class, DataCache.NAME_DEFAULT);
+ assertCacheName(CacheObjectJ.class, DataCache.NAME_DEFAULT);
+ assertCacheName(AppIdCacheObject.class, DataCache.NAME_DEFAULT);
+ }
+
+ private void assertCacheName(Class cls, String cacheName) {
+ ClassMetaData meta = JPAFacadeHelper.getMetaData(factory, cls);
+ if (cacheName == null)
+ assertNull(meta.getDataCache());
+ else {
+ assertNotNull(meta.getDataCache());
+ assertEquals(cacheName, meta.getDataCache().getName());
+ }
+ }
+
+ // FIXME Seetha Sep 26,2006
+ // not able to replace pm.newQuery(CacheObjectA.class);
+ /*
+ * public void testQueryAggregates() { PersistenceManager pm =
+ * factory.getPersistenceManager(); try { Query q =
+ * pm.newQuery(CacheObjectA.class); q.setResult("max (age)"); Object o =
+ * q.execute(); assertTrue("o must be instanceof Number", o instanceof
+ * Number); } finally { close(pm); } }
+ */
+
+ public void testCache2() {
+ OpenJPAEntityManager em1 =
+ (OpenJPAEntityManager) factory.createEntityManager();
+ OpenJPAEntityManager em2 = null;
+ DataCache cache;
+
+ try {
+ CacheObjectA a1 = (CacheObjectA) em1.find(CacheObjectA.class, oid);
+
+ em2 = (OpenJPAEntityManager) factory2.createEntityManager();
+ CacheObjectA a2 = (CacheObjectA) em2.find(CacheObjectA.class, oid);
+
+ // assert that the oid is in factory2's cache
+ //MetaDataRepository repos2 = factory2.getConfiguration().getMetaDataRepositoryInstance();
+ MetaDataRepository repos2 =
+ ((((OpenJPAEntityManagerFactorySPI) factory2)).getConfiguration())
+ .getMetaDataRepositoryInstance();
+ ClassMetaData meta = repos2
+ .getMetaData(CacheObjectA.class, em2.getClassLoader(), true);
+ cache = meta.getDataCache();
+ assertTrue(cache.contains(oidwithclass));
+
+ // modify the object.
+ startTx(em1);
+ a1.setName(a1.getName() + " changed");
+ endTx(em1);
+ }
+ finally {
+ if (em2 != null)
+ endEm(em2);
+ endEm(em1);
+ }
+
+ // if the cache is a coherent one, then the changes should be
+ // seen. Otherwise, they should not.
+ if (isCacheCoherent() || factory == factory2)
+ assertTrue("key " + oid + " was not in cache; should have been",
+ cache.contains(oidwithclass));
+ else
+ assertFalse("key " + oid + " was in cache; should not have been",
+ cache.contains(oidwithclass));
+ }
+
+ public void testTimeouts1() throws Exception {
+ timeoutsTest1(1);
+ }
+
+ public void timeoutsTest1(int tries) throws Exception {
+ // this crazy for looping stuff is here because we're seeing
+ // intermittent failures with the garbage collector kicking in
+ // during testing. So, this decreases the chances that that
+ // will happen.
+ Exception e = null;
+ int i;
+ for (i = 0; i < tries; i++) {
+ try {
+ timeoutsHelper(factory);
+ // any successes will pass the test
+ return;
+ }
+ catch (Exception ex) {
+ e = ex;
+ }
+ }
+
+ throw e;
+ }
+
+ public void testTimeouts2() throws Exception {
+ timeoutsTest2(30);
+ }
+
+ public void timeoutsTest2(int tries) throws Exception {
+ Error e = null;
+ for (int i = 0; i < tries; i++) {
+ try {
+ timeoutsHelper(timeoutFactory);
+ // any successes will pass the test
+ return;
+ }
+ catch (AssertionFailedError afe) {
+ e = afe;
+ }
+ }
+
+ throw e;
+ }
+
+ private void timeoutsHelper(OpenJPAEntityManagerFactory factory)
+ throws Exception {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ startTx(em);
+
+ CacheObjectE e = new CacheObjectE("e");
+ em.persist(e);
+
+ CacheObjectF f = new CacheObjectF("f");
+ em.persist(f);
+
+ CacheObjectG g = new CacheObjectG("g");
+ em.persist(g);
+
+ CacheObjectH h = new CacheObjectH("h");
+ em.persist(h);
+
+ endTx(em);
+
+ Object[] ids = new Object[4];
+ ids[0] = new Id(CacheObjectE.class, em.getObjectId(e).toString());
+ ids[1] = new Id(CacheObjectF.class, em.getObjectId(f).toString());
+ ids[2] = new Id(CacheObjectG.class, em.getObjectId(g).toString());
+ ids[3] = new Id(CacheObjectH.class, em.getObjectId(h).toString());
+
+ // build up some queries to test
+
+ // this one should be only on the superclass, since
+ // CacheObjectF has a timeout.
+ Broker broker = JPAFacadeHelper.toBroker(em);
+ org.apache.openjpa.kernel.Query q1 = broker.newQuery(
+ JPQLParser.LANG_JPQL, "select a from "
+ + CacheObjectE.class.getSimpleName() + " a");
+ q1.setCandidateExtent(broker.newExtent(CacheObjectE.class, false));
+ iterate((Collection) q1.execute());
+ assertInCache(q1, Boolean.TRUE);
+
+ org.apache.openjpa.kernel.Query q2 = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectF.class.getSimpleName() + " a");
+ iterate((Collection) q2.execute());
+ assertInCache(q2, Boolean.TRUE);
+
+ DataCache cache = cacheManager(factory).getDataCache(
+ DataCache.NAME_DEFAULT, false);
+ checkCache(cache, ids, new boolean[]{ true, true, true, true });
+
+ // should cause h to be dropped.
+ Thread.currentThread().sleep(551);
+ Thread.yield();
+ checkCache(cache, ids, new boolean[]{ true, true, true, false });
+
+ // if this run has a default timeout (set to 1 sec in the test
+ // case), e should be timed out by this point.
+ //boolean eStatus = !(factory.getConfiguration().getDataCacheTimeout() > 0);
+ boolean eStatus =
+ !((((OpenJPAEntityManagerFactorySPI) factory).getConfiguration())
+ .getDataCacheTimeout() > 0);
+
+ // should cause f to be dropped.
+ Thread.currentThread().sleep(550);
+ Thread.yield();
+ checkCache(cache, ids,
+ new boolean[]{ eStatus, false, true, false });
+
+ // at this point, q2 should be dropped (because its candidate
+ // class is CacheObjectF), and q1 might be dropped, depending
+ // on whether or not we've got a timeout configured.
+ assertInCache(q1, (eStatus) ? Boolean.TRUE : Boolean.FALSE);
+ assertInCache(q2, Boolean.FALSE);
+
+ // should cause g to be dropped.
+ Thread.currentThread().sleep(4050);
+ Thread.yield();
+ checkCache(cache, ids,
+ new boolean[]{ eStatus, false, false, false });
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ public void testQueryTimeouts() throws Exception {
+ queryTimeoutsHelper(factory);
+ queryTimeoutsHelper(timeoutFactory);
+ }
+
+ private void queryTimeoutsHelper(OpenJPAEntityManagerFactory factory)
+ throws Exception {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ startTx(em);
+
+ CacheObjectE e = new CacheObjectE("e");
+ em.persist(e);
+
+ CacheObjectF f = new CacheObjectF("f");
+ em.persist(f);
+
+ endTx(em);
+
+ // build up some queries to test
+ Broker broker = JPAFacadeHelper.toBroker(em);
+ org.apache.openjpa.kernel.Query q1 = broker
+ .newQuery(JPQLParser.LANG_JPQL, "SELECT a FROM CacheObjectE a");
+
+ q1.setCandidateExtent(broker.newExtent(CacheObjectE.class, false));
+ iterate((Collection) q1.execute());
+ assertInCache(q1, Boolean.TRUE);
+
+ org.apache.openjpa.kernel.Query q2 = broker
+ .newQuery(JPQLParser.LANG_JPQL, "SELECT a FROM CacheObjectF a");
+ iterate((Collection) q2.execute());
+ assertInCache(q2, Boolean.TRUE);
+
+ // if this run has a default timeout (set to 1 sec in the test
+ // case), e should be timed out by this point.
+ //boolean eTimedOut = factory.getConfiguration().getDataCacheTimeout() > 0;
+ boolean eTimedOut =
+ ((((OpenJPAEntityManagerFactorySPI) factory).getConfiguration())
+ .getDataCacheTimeout() > 0);
+
+ // should cause f to be dropped.
+ Thread.currentThread().sleep(1001);
+
+ // at this point, q2 should be dropped (because its candidate
+ // class is CacheObjectF), and q1 might be dropped, depending
+ // on whether or not we've got a timeout configured.
+ assertInCache(q1, (eTimedOut) ? Boolean.FALSE : Boolean.TRUE);
+ assertInCache(q2, Boolean.FALSE);
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ public void testQueryImplicitEvictions() throws Exception {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ RuntimeTest1[] helperObjs = new RuntimeTest1[5];
+ helperObjs[0] = new RuntimeTest1();
+ helperObjs[1] = new RuntimeTest1();
+ helperObjs[2] = new RuntimeTest1();
+ helperObjs[3] = new RuntimeTest1();
+ helperObjs[4] = new RuntimeTest1();
+ startTx(em);
+ em.persist(helperObjs[0]);
+ em.persist(helperObjs[1]);
+ em.persist(helperObjs[2]);
+ em.persist(helperObjs[3]);
+ em.persist(helperObjs[4]);
+ endTx(em);
+
+ DataCache cache = cacheManager(factory).getDataCache(
+ DataCache.NAME_DEFAULT, false);
+
+ if (!isOpenJPACache(cache)) {
+ bug(627, "Tangosol cache impl needs modernization");
+ return;
+ }
+
+ if (cache instanceof DelegatingDataCache)
+ cache = ((DelegatingDataCache) cache).getInnermostDelegate();
+ if (cache instanceof ConcurrentDataCache) {
+ CacheMap map = ((ConcurrentDataCache) cache).getCacheMap();
+ map.setCacheSize(3);
+ map.setSoftReferenceSize(0);
+ } else if (cache instanceof ConcurrentDataCache) {
+ CacheMap map = ((ConcurrentDataCache) cache).getCacheMap();
+ map.setCacheSize(3);
+ map.setSoftReferenceSize(0);
+ }
+
+ startTx(em);
+ CacheObjectH h = new CacheObjectH("h");
+ em.persist(h);
+ CacheObjectJ j = new CacheObjectJ("j", h);
+ em.persist(j);
+ endTx(em);
+ Object hoid = em.getObjectId(h);
+ Object joid = em.getObjectId(j);
+
+ Object hoidwithclass = new Id(CacheObjectH.class, hoid.toString());
+ Object joidwithclass = new Id(CacheObjectJ.class, joid.toString());
+ endEm(em);
+
+ // make sure j and h are in cache; may not be if not LRU
+ int attempts = 0;
+ for (; attempts < 100 && !cache.contains(joidwithclass); attempts++)
+ {
+ em = factory.createEntityManager();
+ if (!cache.contains(hoidwithclass))
+ em.find(CacheObjectH.class, hoid);
+ if (!cache.contains(joidwithclass))
+ em.find(CacheObjectJ.class, joid);
+ endEm(em);
+ }
+ assertTrue("Could not get queried objects into cache",
+ attempts < 100);
+
+ // build up a query that uses H in its access path...
+ em = factory.createEntityManager();
+ Broker broker = JPAFacadeHelper.toBroker(em);
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectJ.class.getSimpleName()
+ + " a where a.str = 'h'");
+ iterate((Collection) q.execute());
+ assertInCache(q, Boolean.TRUE);
+ endEm(em);
+
+ // force h out of the cache. we might have to try multiple times
+ // if the cache is not LRU
+ attempts = 0;
+ for (; attempts < 100 && cache.contains(joidwithclass); attempts++)
+ {
+ em = factory.createEntityManager();
+ for (int i = 0; i < 5; i++)
+ em.find(RuntimeTest1.class, em.getObjectId(helperObjs[i]));
+ endEm(em);
+ }
+ assertTrue("Could not kick queried objects out of cache",
+ attempts < 100);
+
+ em = factory.createEntityManager();
+ broker = JPAFacadeHelper.toBroker(em);
+ q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectJ.class.getSimpleName()
+ + " a where a.str = 'h'");
+ try {
+ assertInCache(q, null);
+ }
+ catch (AssertionFailedError e) {
+ bug(626, "query cache invalidation is broken");
+ }
+
+ // ### should test remote events causing queries to evict.
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ // FIXME SEetha Sep 26,2006
+ // not able to replace pm.newQuery(CacheObjectE.class);
+ /*
+ * public void testAllegedQueryOrderingChanges() throws Exception { //
+ * inspired by tsc 3013. pcl: I have not been able to get this // test case
+ * to actually fail. However, during analysis of // 3013's stack traces, I
+ * discovered that the // QueryKey.equals() method did not deal with the
+ * ordering // field correctly, possibly causing the problem.
+ *
+ * OpenJPAEntityManager em = (OpenJPAEntityManager)
+ * factory.createEntityManager(); try { startTx(em,
+ * ()); CacheObjectE e = new CacheObjectE("e"); em.persist(e);
+ * endTx(em); } finally {
+ * endEm(em); }
+ *
+ * em = factory.createEntityManager(); Query q; Collection c; List l; try {
+ * q = em.createQuery(CacheObjectE.class); q.setOrdering("str ascending"); c =
+ * (Collection) q.execute(); l = new LinkedList(c); assertEquals(1,
+ * c.size()); } finally { endEm(em); }
+ *
+ * em = factory.createEntityManager(); try { q =
+ * em.createQuery(CacheObjectE.class); q.setOrdering("str ascending"); c =
+ * (Collection) q.execute(); l = new LinkedList(c); assertEquals(1,
+ * c.size()); } finally { endEm(em); }
+ *
+ * try { em = factory.createEntityManager(); q =
+ * em.createQuery(CacheObjectE.class); q.setOrdering("str descending"); c =
+ * (Collection) q.execute(); assertEquals(1, c.size()); l = new
+ * LinkedList(c); } finally { endEm(em); } }
+ */
+
+ public void testAllegedConcurrentModificationException() throws Exception {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ CacheObjectE e;
+ try {
+ ClassMetaData meta = JPAFacadeHelper.getMetaData(em,
+ CacheObjectE.class);
+ if (!isOpenJPACache(meta.getDataCache()))
+ return;
+
+ startTx(em);
+ e = new CacheObjectE("e");
+ em.persist(e);
+ endTx(em);
+ }
+ finally {
+ endEm(em);
+ }
+
+ em = factory.createEntityManager();
+ try {
+ startTx(em);
+
+ // find the new object...
+ OpenJPAQuery q = em.createQuery("select a FROM "
+ + CacheObjectE.class.getSimpleName()
+ + " a where a.str = 'e'");
+ e = (CacheObjectE) ((Collection) q.getResultList()).iterator()
+ .next();
+
+ // ... and modify the changed object.
+ e.setStr("e2");
+ e.setStr("e3");
+ endTx(em);
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ private boolean isOpenJPACache(DataCache cache) {
+ if (cache instanceof DelegatingDataCache)
+ cache = ((DelegatingDataCache) cache).getInnermostDelegate();
+
+ return cache instanceof ConcurrentDataCache;
+ }
+
+ // ---------- utility methods ----------
+
+ private void checkCache(DataCache cache, Object[] ids, boolean[] stati) {
+ CacheTestHelper.checkCache(this, cache, ids, stati);
+ }
+
+ private void assertInCache(org.apache.openjpa.kernel.Query q,
+ Boolean inCache) {
+ CacheTestHelper.assertInCache(this, q, inCache);
+ }
+
+ private void assertInCache(org.apache.openjpa.kernel.Query q,
+ Boolean inCache, Object[] args) {
+ CacheTestHelper.assertInCache(this, q, inCache, args);
+ }
+
+ private void iterate(Collection c) {
+ CacheTestHelper.iterate(c);
+ }
+
+ public void testInterface() throws Exception {
+ OpenJPAEntityManager newEm =
+ (OpenJPAEntityManager) factory.createEntityManager();
+ startTx(newEm);
+ CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+ CacheObjectC c = new CacheObjectC("blah");
+ a.setRelatedInterface(c);
+ endTx(newEm);
+ Object cId = newEm.getObjectId(c);
+ endEm(newEm);
+
+ newEm = (OpenJPAEntityManager) factory.createEntityManager();
+ a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+
+ CacheObjectInterface c2 = a.getRelatedInterface();
+ assertNotNull(c2);
+
+ assertEquals(cId, newEm.getObjectId(c2));
+ }
+
+ public void testQueriesOnCollectionsDontUseCache() {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ try {
+ startTx(em);
+ CacheObjectE e = new CacheObjectE("e");
+ em.persist(e);
+ endTx(em);
+ }
+ finally {
+ endEm(em);
+ }
+
+ em = (OpenJPAEntityManager) factory.createEntityManager();
+ OpenJPAQuery q;
+ Collection c;
+ try {
+ q = em.createQuery("select a FROM "
+ + CacheObjectE.class.getSimpleName()
+ + " a where a.str = 'e'");
+ c = new ArrayList((Collection) q.getResultList());
+ assertEquals(1, c.size());
+ q.closeAll();
+ }
+ finally {
+ endEm(em);
+ }
+
+ try {
+ em = (OpenJPAEntityManager) factory.createEntityManager();
+ q = em.createQuery("select a FROM "
+ + CacheObjectE.class.getSimpleName()
+ + " a where a.str = 'e'");
+ q.setCandidateCollection(new ArrayList(0));
+ c = (Collection) q.getResultList();
+ assertEquals(0, c.size());
+ q.closeAll();
+ }
+ finally {
+ endEm(em);
+ }
+ }
+
+ public void testDFGFieldsLoaded1() {
+ dfgFieldsLoadedHelper(false);
+ }
+
+ public void testDFGFieldsLoaded2() {
+ dfgFieldsLoadedHelper(true);
+ }
+
+ public void dfgFieldsLoadedHelper(boolean related) {
+ OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ startTx(em);
+ OpenJPAQuery q;
+ Collection c;
+ try {
+
+ q = em.createQuery(
+ "select a FROM " + CacheObjectA.class.getSimpleName()
+ + " a where a.name = :pName").setParameter("pName",
+ ORIG_NAME);
+
+ c = new ArrayList((Collection) q.getResultList());
+ assertEquals(1, c.size());
+ CacheObjectA a = (CacheObjectA) c.iterator().next();
+ if (related)
+ a.getRelatedArray();
+ em.detach(a);
+ assertEquals(ORIG_NAME, a.getName());
+ q.closeAll();
+ }
+ finally {
+ rollbackTx(em);
+ endEm(em);
+ }
+ }
+
+ // FIXME Seetha Sep 26,2006
+ /*
+ * public void testQueriesAfterModificationAreNotInCache() {
+ * OpenJPAEntityManager em = (OpenJPAEntityManager)
+ * factory.createEntityManager(); OpenJPAEntityManager em2 =
+ * (OpenJPAEntityManager) factory.createEntityManager();
+ *
+ * //FIXME Seetha Sep 26,2006 //em.setIgnoreCache(false);
+ * //em2.setIgnoreCache(false); ((FetchPlan) em.getFetchPlan()).
+ * setFlushBeforeQueries(FetchPlan.FLUSH_TRUE); ((FetchPlan)
+ * em2.getFetchPlan()). setFlushBeforeQueries(FetchPlan.FLUSH_TRUE);
+ *
+ * try { startTx(em); CacheObjectE e = new
+ * CacheObjectE("e"); em.persist(e); endTx(em,
+ * ());
+ *
+ * startTx(em);
+ * // first, a query that should get into the cache. Broker broker =
+ * JPAFacadeHelper.toBroker(em); org.apache.openjpa.kernel.Query q =
+ * broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, "str ==
+ * \"e\""); Collection c = (Collection) q.execute(); for (Iterator iter =
+ * c.iterator(); iter.hasNext();) iter.next();
+ *
+ * assertEquals(1, c.size()); assertInCache(q, Boolean.TRUE);
+ *
+ * Broker broker2 = JPAFacadeHelper.toBroker(em2);
+ * org.apache.openjpa.kernel.Query q2 = broker2.newQuery(q.getLanguage(),
+ * q);
+ * // make some modifications and look again. Should return // two results.
+ * e = new CacheObjectE("e"); em.persist(e);
+ *
+ * q = broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, "str ==
+ * \"e\""); c = (Collection) q.execute(); assertEquals(2, c.size()); for
+ * (Iterator iter = c.iterator(); iter.hasNext();) iter.next();
+ * // original query should still be in cache assertInCache(q2,
+ * Boolean.TRUE);
+ *
+ * Collection c2 = (Collection) q2.execute(); assertEquals(1, c2.size());
+ * // new query should not make it into cache
+ *
+ * q = broker .newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, null); c =
+ * (Collection) q.execute(); assertEquals(2, c.size()); for (Iterator iter =
+ * c.iterator(); iter.hasNext();) iter.next();
+ *
+ * assertInCache(q, Boolean.FALSE); } finally {
+ * rollbackTx(em);
+ * endEm(em);
+ * endEm(em2); } }
+ */
+
+ public void testCachedQueryClosureReleasesResources() {
+ // PersistenceManagerFactory factory =
+ // KodoHelper.createEntityManagerFactory ();
+ EntityManager initEm = factory.createEntityManager();
+ startTx(initEm);
+ CacheObjectE e = new CacheObjectE("e");
+ initEm.persist(e);
+ endTx(initEm);
+ endEm(initEm);
+
+ Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectE.class.getSimpleName()
+ + " a where a.str = 'e'");
+ Collection c = (Collection) q.execute();
+ for (Iterator iter = c.iterator(); iter.hasNext();)
+ iter.next();
+
+ assertEquals(1, c.size());
+ assertInCache(q, Boolean.TRUE);
+
+ ImplHelper.close(c);
+
+ broker.close();
+ }
+
+ public void testMutableSCOsAreConverted() {
+ OpenJPAEntityManager em0 = (OpenJPAEntityManager) factory
+ .createEntityManager();
+ OpenJPAEntityManager em1 = (OpenJPAEntityManager) factory
+ .createEntityManager();
+
+ startTx(em0);
+ CacheObjectA a = (CacheObjectA) em0.find(CacheObjectA.class, oid);
+
+ Date d = new Date();
+ a.setDate(d);
+
+ endTx(em0);
+ DataCache cache = cacheManager(factory).getDataCache(
+ DataCache.NAME_DEFAULT, false);
+ assertTrue(cache.contains(oidwithclass));
+ cache.remove(oidwithclass);
+
+ a = (CacheObjectA) em1.find(CacheObjectA.class, oid);
+ assertTrue(cache.contains(oidwithclass));
+
+ try {
+ PCData data = cache.get(oidwithclass);
+ ClassMetaData meta =
+ ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence
+ .cast(factory)).getConfiguration()
+ .getMetaDataRepositoryInstance().getMetaData(a.getClass(),
+ null, false);
+ FieldMetaData fmd = meta.getField("date");
+ d = (Date) data.getData(fmd.getIndex());
+ Broker broker = JPAFacadeHelper.toBroker(em1);
+ OpenJPAStateManager sm = broker.getStateManager(a);
+ assertTrue(sm == ((ProxyDate) a.getDate()).getOwner());
+ assertEquals(Date.class, d.getClass());
+ }
+ finally {
+ endEm(em0);
+ endEm(em1);
+ }
+ }
+
+ public void testEmptyResultsAreCached() {
+ Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+ org.apache.openjpa.kernel.Query q = broker.newQuery(
+ JPQLParser.LANG_JPQL, "Select a FROM "
+ + CacheObjectAChild1.class.getSimpleName()
+ + " a where a.name = 'testEmptyResultsAreCached'");
+ Collection c = (Collection) q.execute();
+ assertEquals(0, c.size());
+ assertInCache(q, Boolean.TRUE);
+ broker.close();
+ }
+
+ private void doassertTrue(EntityManager em, String name, int age)
+ throws Exception {
+ CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+ assertTrue(name.equals(a.getName()));
+ assertTrue(a.getAge() == age);
+ endEm(em);
+ }
+
+ private void assertNew(CacheObjectA a) {
+ assertTrue(NEW_NAME.equals(a.getName()));
+ assertTrue(ORIG_AGE == a.getAge());
+ }
+
+ private void assertOld(CacheObjectA a) {
+ assertTrue(ORIG_NAME.equals(a.getName()));
+ assertTrue(ORIG_AGE == a.getAge());
+ }
+
+ private DataCacheManager cacheManager(OpenJPAEntityManagerFactory factory) {
+ return CacheTestHelper
+ .cacheManager(JPAFacadeHelper.toBrokerFactory(factory));
+ }
+
+ private void close(EntityManager em) {
+ rollbackTx(em);
+ endEm(em);
+ }
+
+ private void close(Broker broker) {
+ if (broker.isActive())
+ broker.rollback();
+ broker.close();
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (int i = 0; i < args.length; i++) {
+ String type = args[i];
+
+ CacheTest c;
+ if (type.equals("tcp")) {
+ c = new DistributedCacheTest("time test",
+ ConcurrentDataCache.class);
+ } else if (type.equals("jms")) {
+ c = new DistributedCacheTest("time test",
+ ConcurrentDataCache.class);
+ } else {
+ c = new TestLocalCache("time test");
+ }
+
+ c.setUp();
+ long start = System.currentTimeMillis();
+ int count = 1000;
+ for (int j = 0; j < count; j++) {
+ c.doassertTrue(c.factory.createEntityManager(), NEW_NAME,
+ ORIG_AGE);
+ }
+ System.out.println(count + " iterations in "
+ + (System.currentTimeMillis() - start) + " millis");
+ c.tearDown();
+ }
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,74 @@
+//This class access the private class QueryCacheStoreQuery.
+//So this has to be in kodo.datacache package
+/*
+ * 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.openjpa.persistence.datacache;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.openjpa.datacache.QueryCacheStoreQuery.CachedList;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerImpl;
+import org.apache.openjpa.kernel.QueryImpl;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.lib.rop.ListResultList;
+import org.apache.openjpa.lib.rop.ListResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+
+/**
+ * <p>
+ * Used to mark cached query results for testing.
+ * </p>
+ */
+public class CacheTestBroker extends BrokerImpl {
+
+ protected QueryImpl newQueryImpl(String language, StoreQuery sq) {
+ return new CacheTestQuery(this, language, sq);
+ }
+
+ public static class CachedQueryResult extends ListResultList {
+
+ public CachedQueryResult(List list) {
+ super(list);
+ }
+ }
+
+ private static class CacheTestQuery extends QueryImpl {
+
+ public CacheTestQuery(Broker broker, String language,
+ StoreQuery query) {
+ super(broker, language, query);
+ }
+
+ protected Object toResult(StoreQuery q, StoreQuery.Executor ex,
+ ResultObjectProvider rop, StoreQuery.Range range)
+ throws Exception {
+ boolean cached = rop instanceof ListResultObjectProvider
+ && (((ListResultObjectProvider) rop)
+ .getDelegate() instanceof CachedList ||
+ ((ListResultObjectProvider) rop)
+ .getDelegate() == Collections.EMPTY_LIST);
+ Object res = super.toResult(q, ex, rop, range);
+ if (cached && res instanceof List)
+ return new CachedQueryResult((List) res);
+ return res;
+ }
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,118 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.QueryCache;
+import org.apache.openjpa.datacache.QueryKey;
+import org.apache.openjpa.datacache.DataCacheManager;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+class CacheTestHelper {
+
+ static void checkCache(AbstractTestCase tc, DataCache cache, Object[] ids,
+ boolean[] stati) {
+ for (int i = 0; i < ids.length; i++) {
+ if (stati[i])
+ tc.assertTrue("id " + i + " (" + ids[i]
+ + ") was not in cache; should have been",
+ cache.contains(ids[i]));
+ else
+ tc.assertFalse("id " + i + " (" + ids[i]
+ + ") was in cache; should not have been",
+ cache.contains(ids[i]));
+ }
+ }
+
+ static void assertInCache(AbstractTestCase tc, Query q, Boolean inCache) {
+ assertInCache(tc, q, inCache, new Object[0]);
+ }
+
+ /**
+ * Test whether the given query has valid cached results.
+ *
+ * @param inCache if {@link Boolean#TRUE}, the query must have valid
+ * cached results; if {@link Boolean#FALSE} the query
+ * must not have any cached results; if null the
+ * query may have cached results, but they cannot be
+ * valid (i.e. they can't be returned to the user)
+ */
+ static void assertInCache(AbstractTestCase tc, Query query, Boolean inCache,
+ Object[] args) {
+ QueryKey qk = QueryKey.newInstance(query, args);
+ Broker broker = query.getBroker();
+ BrokerFactory factory = broker.getBrokerFactory();
+
+ QueryCache qc = cacheManager(factory).getSystemQueryCache();
+ if (inCache == Boolean.FALSE && qc.get(qk) != null) {
+ tc.fail("query should not be in cache; was.");
+ } else if (inCache == Boolean.TRUE || (inCache == null
+ && qc.get(qk) != null)) {
+ Object res = (args == null) ? query.execute()
+ : query.execute(args);
+ if (inCache == Boolean.TRUE &&
+ !isCachedResult(res, inCache, query.getBroker()))
+ tc.fail("query should be in cache; was not.");
+ else if (inCache == null &&
+ isCachedResult(res, inCache, query.getBroker()))
+ tc.fail("query should not be returned to user; was.");
+ query.closeAll();
+ }
+ }
+
+ private static boolean isCachedResult(Object res, Boolean expected,
+ Broker broker) {
+ // we can only check for a CachedQueryResult if the
+ // Broker was configured to be a CacheTestBroker
+ if (!(broker instanceof CacheTestBroker))
+ throw new IllegalArgumentException("Broker was not set to be "
+ + "a CacheTestBroker, making it impossible to verify "
+ + "if query result is cached");
+
+ if (res instanceof Collection)
+ return res instanceof CacheTestBroker.CachedQueryResult;
+ // no way to tell if unique results from cache
+ return expected.booleanValue();
+ }
+
+ static void iterate(Collection c) {
+ // iterate through the collection so that the results have an
+ // opportunity to register themselves with the PM.
+ int count = 0;
+ for (Iterator iter = c.iterator(); iter.hasNext();) {
+ try {
+ count++;
+ iter.next();
+ } catch (NoSuchElementException e) {
+ throw e;
+ }
+ }
+ }
+
+ static DataCacheManager cacheManager(BrokerFactory factory) {
+ return factory.getConfiguration().getDataCacheManagerInstance();
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,81 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+import org.apache.openjpa.lib.conf.Configurations;
+
+/**
+ * Distributed cache test.
+ */
+public class DistributedCacheTest
+ extends CacheTest {
+
+ private static String cache = null;
+ private static String queryCache = null;
+ private static String provider = null;
+
+ public static void setCache(String plugin) {
+ cache = plugin;
+ }
+
+ public static void setQueryCache(String plugin) {
+ queryCache = plugin;
+ }
+
+ public static void setRemoteCommitProvider(String plugin) {
+ provider = plugin;
+ }
+
+ public DistributedCacheTest(String test) {
+ super(test);
+ }
+
+ public DistributedCacheTest(String test, Class testClass) {
+ super(test);
+ }
+
+ protected String[] getConfs() {
+ return getConfs(true);
+ }
+
+ protected String[] getConfs2() {
+ return getConfs(false);
+ }
+
+ protected String[] getConfs(boolean confs1) {
+ String fullProvider = provider;
+ String props = Configurations.getProperties
+ (System.getProperty("openjpa.RemoteCommitProvider"));
+ if (props == null || props.length() == 0)
+ props = Configurations.getProperties(provider);
+ else
+ fullProvider = Configurations.getPlugin(provider, props);
+ if (props == null || props.length() == 0)
+ throw new IllegalStateException
+ ("must specify -Dkodo.RemoteCommitProvider=?");
+
+ return new String[]{
+ // use this property to differentiate factory
+ "openjpa.DataCache", cache + ", true(Name=" + confs1 + ")",
+ "openjpa.QueryCache", queryCache,
+ "openjpa.RemoteCommitProvider", fullProvider,
+ "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+ };
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,41 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+/**
+ * Multi-threaded cache load test for running in the autobuild.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class TestCacheMultiThreadedLoad
+ extends CacheLoadTest {
+
+ public TestCacheMultiThreadedLoad() {
+ // pared down iteration and thread count for running in the
+ // autobbuild
+ interationCount = 400;
+ threadCount = 10;
+ }
+
+ public boolean skipTest() {
+ return true;
+ }
+}
+
+
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,55 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+/**
+ * Test data caching across multiple factories in the same JVM, using
+ * the single-JVM commit provider to communicate updates..
+ */
+public class TestConcurrentDataCache
+ extends CacheTest {
+
+ public TestConcurrentDataCache(String test) {
+ super(test);
+ }
+
+ protected String[] getConfs() {
+ return new String[]{
+ // the second cache is there solely to differentiate between
+ // this PMF and the PMF created from confs2 below
+ "openjpa.DataCache",
+ "concurrent, concurrent(Name=differentiatingProperty1)",
+ "openjpa.QueryCache", "true",
+ "openjpa.RemoteCommitProvider", "sjvm",
+ "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+ };
+ }
+
+ protected String[] getConfs2() {
+ return new String[]{
+ // the second cache is there solely to differentiate between
+ // this PMF and the PMF created from confs above
+ "openjpa.DataCache",
+ "concurrent, concurrent(Name=differentiatingProperty2)",
+ "openjpa.QueryCache", "concurrent",
+ "openjpa.RemoteCommitProvider", "sjvm",
+ "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+ };
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,46 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+/**
+ * Extend the single-JVM cache test to test dynamic pcdata.
+ */
+public class TestDataCachePCDataGenerator
+ extends TestSJVMCache {
+
+ public TestDataCachePCDataGenerator(String test) {
+ super(test);
+ }
+
+ protected String[] getConfs() {
+ return addGenerator(super.getConfs());
+ }
+
+ protected String[] getConfs2() {
+ return addGenerator(super.getConfs2());
+ }
+
+ private String[] addGenerator(String[] confs) {
+ String[] copy = new String[confs.length + 2];
+ System.arraycopy(confs, 0, copy, 0, confs.length);
+ copy[confs.length] = "openjpa.DynamicDataStructs";
+ copy[confs.length + 1] = "true";
+ return copy;
+ }
+}