/* | |
* 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(); | |
} | |
} | |
} |