blob: 8da84e930faa91cdc6fcfb333eda45dce3f07738 [file] [log] [blame]
/*
* 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.datacache.ConcurrentDataCache;
import org.apache.openjpa.datacache.DataCache;
import org.apache.openjpa.datacache.DataCacheManager;
import org.apache.openjpa.datacache.DelegatingDataCache;
import org.apache.openjpa.datacache.QueryCache;
import org.apache.openjpa.datacache.TypesChangedEvent;
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.persistence.common.utils.AbstractTestCase;
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.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;
import junit.framework.AssertionFailedError;
/**
* ### 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;
}
@Override
public void setUp() throws Exception {
/*
* OpenJPA does not seem to support plural configuration properties. (Although it seems
* that Kodo does...) Until OpenJPA is updated to support this multiple configuration
* setting, the following configuration item will be disabled...
*
* Specifically, this type of configuration is currently not allowed...
* <property name="openjpa.DataCache" value="true, true(Name=xxx)"/>
*/
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);
}
}
@Override
public void tearDown() throws Exception {
endEm(em);
em = null;
repos = null;
try {
closeEMF(factory);
}
catch (Exception e) {
}
factory = null;
try {
closeEMF(factory2);
}
catch (Exception e) {
}
factory2 = null;
try {
closeEMF(timeoutFactory);
}
catch (Exception e) {
}
super.tearDown();
timeoutFactory = null;
oid = null;
parentOid = 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");
/*
* I don't think this is a bug, nor should this exception
* occur. Since we're doing a find() operation above and this
* field (RelatedObj) has a default Fetch type of EAGER, then
* we should be re-loading the RelatedObj and it will be put back
* in the cache... So, by commenting out the above find()
* operation (or overriding the default Fetch type to EAGER), then
* this assertFalse works...
*/
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,
ORIG_AGE});
l = (List) q.execute(new Object[]{ ORIG_NAME,
ORIG_AGE});
iterate(l);
q2p1 = System.currentTimeMillis() - start;
assertEquals(origSize, l.size());
start = System.currentTimeMillis();
l2 = (List) q.execute(new Object[]{ ORIG_NAME,
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);
// Query results are no longer dependent on cacheability of an entity.
assertInCache(q, Boolean.TRUE);
}
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);
// Query results are no longer dependent on cacheability of an entity.
assertInCache(q, Boolean.TRUE);
}
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);
/*
* Due to the problem documented in the setup() routine, the following tests are not valid...
*/
// assertCacheName(CacheObjectBChild1.class, null);// sub-classes should inherit parent's @Cacheable setting
// assertCacheName(CacheObjectC.class, "not-the-default-cache"); multiple datacache instantiation not working...
// 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(30);
}
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);
// get starting time for sleep calculations below
Date startTime = new Date();
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);
// get post-persist time for sleep calculations below
Date persistTime = new Date();
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);
Date currentTime = new Date();
long diff = (currentTime.getTime() - startTime.getTime());
long diff2 = (currentTime.getTime() - persistTime.getTime());
long sleep = 0;
getLog().info("CacheTest.timeoutsHelper() testing all are still in the cache, elapsed time="+diff);
DataCache cache = cacheManager(factory).getDataCache(
DataCache.NAME_DEFAULT, false);
diff = Math.max(diff, diff2);
if (diff < 450) {
// all should still be in the cache
checkCache(cache, ids, new boolean[]{ true, true, true, true });
} else {
// need to skip the test on slow systems or when using remote DB connections
getLog().warn("CacheTest.timeoutsHelper() skipping checkCache(all, <500) because diff=" +
diff + " and diff2=" + diff2);
}
// should cause h to be dropped (timeout=500)
currentTime = new Date();
diff = (currentTime.getTime() - startTime.getTime());
diff2 = (currentTime.getTime() - persistTime.getTime());
sleep = Math.min((800 - diff), (800 - diff2));
if (sleep < 0) {
// we already missed the window
getLog().warn("CacheTest.timeoutsHelper() skipping sleep for checkCache(h=500) because sleep="+sleep);
} else if (sleep > 10) {
getLog().info("CacheTest.timeoutsHelper() testing h to be dropped by waiting sleep="+sleep);
Thread.currentThread();
Thread.sleep(700);
Thread.yield();
} else {
sleep = 0;
}
// recalc diff again
currentTime = new Date();
diff = (currentTime.getTime() - startTime.getTime());
diff2 = (currentTime.getTime() - persistTime.getTime());
diff = Math.max(diff, diff2);
if (diff > 600 && diff < 900) {
// only h should be dropped
checkCache(cache, ids, new boolean[]{ true, true, true, false });
} else {
// need to skip the test on slow systems or when using remote DB connections
getLog().warn("CacheTest.timeoutsHelper() skipping checkCache(h=500) because diff=" + diff +
" and diff2=" + diff2);
}
// 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 (timeout=1000)
currentTime = new Date();
diff = currentTime.getTime() - startTime.getTime();
diff2 = (currentTime.getTime() - persistTime.getTime());
diff = Math.max(diff, diff2);
sleep = 2000 - diff;
if (sleep < 0) {
// we already missed the window
getLog().warn("CacheTest.timeoutsHelper() skipping sleep for checkCache(f=000) because sleep="+sleep);
} else if (sleep > 10) {
getLog().info("CacheTest.timeoutsHelper() testing f to be dropped by waiting sleep="+sleep);
Thread.currentThread();
Thread.sleep(sleep);
Thread.yield();
} else {
sleep = 0;
}
// recalc diff again
currentTime = new Date();
diff = currentTime.getTime() - startTime.getTime();
diff2 = currentTime.getTime() - persistTime.getTime();
diff = Math.max(diff, diff2);
if (diff < 4900) {
// e is conditional, h and f should be dropped, but not g yet
checkCache(cache, ids, new boolean[]{ eStatus, false, true, false });
} else {
// need to skip the test on slow systems or when using remote DB connections
getLog().warn("CacheTest.timeoutsHelper() skipping checkCache(f=1000) because diff="+diff);
}
// 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 (timeout=5000)
currentTime = new Date();
diff = currentTime.getTime() - startTime.getTime();
diff2 = currentTime.getTime() - persistTime.getTime();
diff = Math.max(diff, diff2);
sleep = 6000 - diff;
if (sleep > 0) {
getLog().info("CacheTest.timeoutsHelper() testing g to be dropped by waiting sleep="+sleep);
Thread.currentThread();
Thread.sleep(sleep);
Thread.yield();
}
// all of them should be dropped now, since diff > 5000
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);
// get starting time for sleep calculations below
Date startTime = new Date();
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.
Date currentTime = new Date();
long diff = currentTime.getTime() - startTime.getTime();
long sleep = 2000 - diff;
if (sleep > 0) {
getLog().trace("CacheTest.queryTimeoutsHelper() testing f to be dropped by waiting sleep="+sleep);
Thread.currentThread();
Thread.sleep(sleep);
Thread.yield();
}
// 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);
}
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);
/*
* Not a valid test... At least not with the current implementation...
*
* Just removing items from the DataCache (as done via the previous loop) is not sufficient
* to remove the entries from the QueryCache. Currently, this notification is done at the end
* of a transaction after inserts, updates, and deletes have been performed. Then, the
* updateCaches() method is invoked on the DataCacheStoreManager which will flow the request to
* the QueryCache. With no direct updates to the "Entities of interest", then there's nothing to
* flow over to the QueryCache for cleanup. Even putting the above loop within a transaction is
* not sufficient, since there have been no updates to the "Entities of interest".
*/
// 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();
}
}
}