You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2010/03/30 05:43:20 UTC
svn commit: r928968 - in /openjpa/branches/2.0.x:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-kernel/src/main/java/org/apache/openjpa/datacache/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-persistence-jdbc/src...
Author: curtisr7
Date: Tue Mar 30 03:43:20 2010
New Revision: 928968
URL: http://svn.apache.org/viewvc?rev=928968&view=rev
Log:
OPENAJPA-1603: Decouple the QueryCache from the DataCache. Code contributed by Mike Dick and Rick Curtis.
Added:
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java (with props)
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java (with props)
Modified:
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Tue Mar 30 03:43:20 2010
@@ -30,12 +30,15 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.datacache.QueryCache;
+import org.apache.openjpa.datacache.QueryCacheStoreQuery;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.OrphanedKeyAction;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
@@ -295,6 +298,11 @@ public class JDBCStoreManager
return exists(mapping, sm.getObjectId(), context);
}
+ public boolean isCached(List<Object> oids, BitSet edata) {
+ // JDBCStoreManager doesn't store oids in memory.
+ return false;
+ }
+
private boolean exists(ClassMapping mapping, Object oid, Object context) {
// add where conditions on base class to avoid joins if subclass
// doesn't use oid as identifier
@@ -455,8 +463,9 @@ public class JDBCStoreManager
// Check if the owner has eagerly loaded ToMany relations.
for (int i = 0; i < fms.length; i++) {
if (res.getEager(fms[i]) != null) {
- if (!fms[i].getElement().isTypePC())
+ if (!fms[i].getElement().isTypePC()) {
continue;
+ }
Object coll = owner.fetchObject(fms[i].getIndex());
if (coll instanceof Map)
coll = ((Map)coll).values();
@@ -471,24 +480,23 @@ public class JDBCStoreManager
for (Iterator<?> itr = ((Collection<?>) coll).iterator();
itr.hasNext();) {
PersistenceCapable pc = (PersistenceCapable) itr.next();
-
- if (pc == null)
+ if (pc == null) {
continue;
-
- OpenJPAStateManager sm = (OpenJPAStateManager) pc.
- pcGetStateManager();
- FieldMapping[] fmd = ((ClassMapping) sm.getMetaData()).
- getFieldMappings();
+ }
+ OpenJPAStateManager sm = (OpenJPAStateManager) pc.pcGetStateManager();
+ ClassMapping cm =
+ (ClassMapping) _conf.getMetaDataRepositoryInstance().getCachedMetaData(pc.getClass());
+ FieldMapping[] fmd = cm.getFieldMappings();
for (int j = 0; j < fmd.length; j++) {
- Object oid = sm.getIntermediate(fmd[j].getIndex());
- // if oid was setIntermediate() previously
- // and it is the same as the owner,
- // then set the inverse relation
- if (oid != null &&
- oid.equals(owner.getObjectId())) {
- sm.storeObject(fmd[j].getIndex(),
- owner.getPersistenceCapable());
- break;
+ // don't check the oids for basic fields.
+ if (fmd[j].isTypePC()) {
+ Object oid = sm.getIntermediate(fmd[j].getIndex());
+ // if oid was setIntermediate() previously and it is the same as the owner,generate
+ // then set the inverse relation
+ if (oid != null && oid.equals(owner.getObjectId())) {
+ sm.storeObject(fmd[j].getIndex(), owner.getPersistenceCapable());
+ break;
+ }
}
}
}
@@ -911,16 +919,33 @@ public class JDBCStoreManager
return paged;
}
- public StoreQuery newQuery(String language) {
+ private StoreQuery newStoreQuery(String language) {
ExpressionParser ep = QueryLanguages.parserForLanguage(language);
- if (ep != null)
+ if (ep != null) {
return new JDBCStoreQuery(this, ep);
- if (QueryLanguages.LANG_SQL.equals(language))
+ }
+ if (QueryLanguages.LANG_SQL.equals(language)) {
return new SQLStoreQuery(this);
- if (QueryLanguages.LANG_PREPARED_SQL.equals(language))
+ }
+ if (QueryLanguages.LANG_PREPARED_SQL.equals(language)) {
return new PreparedSQLStoreQuery(this);
+ }
return null;
}
+
+ public StoreQuery newQuery(String language) {
+ StoreQuery sq = newStoreQuery(language);
+ if (sq == null || QueryLanguages.parserForLanguage(language) == null) {
+ return sq;
+ }
+
+ QueryCache queryCache = _ctx.getConfiguration().getDataCacheManagerInstance().getSystemQueryCache();
+ if (queryCache == null) {
+ return sq;
+ }
+
+ return new QueryCacheStoreQuery(sq, queryCache);
+ }
public FetchConfiguration newFetchConfiguration() {
return new JDBCFetchConfigurationImpl();
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java Tue Mar 30 03:43:20 2010
@@ -57,7 +57,11 @@ public class DataCacheManagerImpl
public void initialize(OpenJPAConfiguration conf, ObjectValue dataCache, ObjectValue queryCache) {
_conf = conf;
+ _queryCache = (QueryCache) queryCache.instantiate(QueryCache.class, conf);
+ if (_queryCache != null)
+ _queryCache.initialize(this);
_cache = (DataCache) dataCache.instantiate(DataCache.class, conf);
+
if (_cache == null)
return;
@@ -69,9 +73,7 @@ public class DataCacheManagerImpl
_policy = conf.getCacheDistributionPolicyInstance();
_cache.initialize(this);
- _queryCache = (QueryCache) queryCache.instantiate(QueryCache.class, conf);
- if (_queryCache != null)
- _queryCache.initialize(this);
+
}
public DataCache getSystemDataCache() {
@@ -155,6 +157,7 @@ public class DataCacheManagerImpl
_includedTypes = includedTypes;
_excludedTypes = excludedTypes;
}
+
/**
* Affirms the given class is eligible to be cached according to the cache mode
* and the cache enable flag on the given metadata.
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java Tue Mar 30 03:43:20 2010
@@ -34,14 +34,11 @@ import org.apache.openjpa.kernel.DataCac
import org.apache.openjpa.kernel.DataCacheStoreMode;
import org.apache.openjpa.kernel.DelegatingStoreManager;
import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.FindCallbacks;
import org.apache.openjpa.kernel.LockLevels;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.kernel.QueryLanguages;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.kernel.StoreManager;
-import org.apache.openjpa.kernel.StoreQuery;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.util.OpenJPAId;
@@ -228,22 +225,6 @@ public class DataCacheStoreManager
evictTypes(_ctx.getUpdatedTypes());
}
- // and notify the query cache. notify in one batch to reduce synch
- QueryCache queryCache = _ctx.getConfiguration().
- getDataCacheManagerInstance().getSystemQueryCache();
- if (queryCache != null) {
- Collection<Class<?>> pers = _ctx.getPersistedTypes();
- Collection<Class<?>> del = _ctx.getDeletedTypes();
- Collection<Class<?>> up = _ctx.getUpdatedTypes();
- int size = pers.size() + del.size() + up.size();
- if (size > 0) {
- Collection<Class<?>> types = new ArrayList<Class<?>>(size);
- types.addAll(pers);
- types.addAll(del);
- types.addAll(up);
- queryCache.onTypesChanged(new TypesChangedEvent(this, types));
- }
- }
}
}
@@ -292,12 +273,31 @@ public class DataCacheStoreManager
public boolean exists(OpenJPAStateManager sm, Object edata) {
DataCache cache = _mgr.selectCache(sm);
- if (cache != null && !isLocking(null)
- && cache.contains(sm.getObjectId()))
+ if (cache != null && !isLocking(null) && cache.contains(sm.getObjectId()))
return true;
return super.exists(sm, edata);
}
+ public boolean isCached(List<Object> oids, BitSet edata) {
+ // If using partitioned cache, we were and still are broke.
+ DataCache cache = _mgr.getSystemDataCache();
+ if (cache != null && !isLocking(null)) {
+ // BitSet size is not consistent.
+ for(int i = 0; i < oids.size(); i++) {
+ Object oid = oids.get(i);
+ // Only check the cache if we haven't found the current oid.
+ if (edata.get(i) == false && cache.contains(oid)) {
+ edata.set(i);
+ }
+ }
+ if(edata.cardinality()==oids.size()){
+ return true;
+ }
+ }
+
+ return super.isCached(oids, edata);
+ }
+
public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
DataCache cache = _mgr.selectCache(sm);
if (cache == null || sm.isEmbedded())
@@ -660,22 +660,6 @@ public class DataCacheStoreManager
.fireLocalStaleNotification(oid);
}
- public StoreQuery newQuery(String language) {
- StoreQuery q = super.newQuery(language);
-
- // if the query can't be parsed or it's using a non-parsed language
- // (one for which there is no ExpressionParser), we can't cache it.
- if (q == null || QueryLanguages.parserForLanguage(language) == null)
- return q;
-
- QueryCache queryCache = _ctx.getConfiguration().
- getDataCacheManagerInstance().getSystemQueryCache();
- if (queryCache == null)
- return q;
-
- return new QueryCacheStoreQuery(q, queryCache);
- }
-
/**
* Create a new cacheable instance for the given state manager.
*/
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java Tue Mar 30 03:43:20 2010
@@ -33,6 +33,7 @@ import java.util.TreeMap;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.openjpa.datacache.AbstractQueryCache.EvictPolicy;
+import org.apache.openjpa.kernel.DelegatingStoreManager;
import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.LockLevels;
import org.apache.openjpa.kernel.OpenJPAStateManager;
@@ -122,6 +123,7 @@ public class QueryCacheStoreQuery
// get the cached data
QueryResult res = _cache.get(qk);
+
if (res == null)
return null;
if (res.isEmpty())
@@ -153,24 +155,11 @@ public class QueryCacheStoreQuery
int projs = getContext().getProjectionAliases().length;
if (projs == 0) {
- // make sure the data cache contains the oids for the query result;
- // if it doesn't, then using the result could be slower than not
- // using it because of the individual by-oid lookups
- ClassMetaData meta = _repos.getMetaData(getContext().
- getCandidateType(), _sctx.getClassLoader(), true);
- if (meta.getDataCache() == null)
+ // We're only going to return the cached results if we have ALL results cached. This could be improved
+ // in the future to be a little more intelligent.
+ if (getContext().getStoreContext().isCached(res) == false) {
return null;
-
- BitSet idxs = meta.getDataCache().containsAll(res);
-
- // eventually we should optimize this to figure out how many objects
- // the cache is missing and if only a few do a bulk fetch for them
- int len = idxs.length();
- if (len < res.size())
- return null;
- for (int i = 0; i < len; i++)
- if (!idxs.get(i))
- return null;
+ }
}
return new CachedList(res, projs != 0, _sctx);
}
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java Tue Mar 30 03:43:20 2010
@@ -200,14 +200,11 @@ public class QueryKey
// since the class change framework deals with least-derived types,
// record the least-derived access path types
meta = metas[i];
- if (meta.getDataCache() != null)
- accessPathClassNames.add(meta.getDescribedType().getName());
- while (meta.getPCSuperclass() != null)
- meta = meta.getPCSuperclassMetaData();
-
- // ensure that this metadata is cacheable
- if (meta.getDataCache() == null)
- return null;
+ accessPathClassNames.add(meta.getDescribedType().getName());
+ while (meta.getPCSuperclass() != null) {
+ meta = meta.getPCSuperclassMetaData();
+ }
+
accessPathClassNames.add(meta.getDescribedType().getName());
}
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Tue Mar 30 03:43:20 2010
@@ -51,6 +51,8 @@ import org.apache.commons.lang.StringUti
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.QueryCache;
+import org.apache.openjpa.datacache.TypesChangedEvent;
import org.apache.openjpa.ee.ManagedRuntime;
import org.apache.openjpa.enhance.PCRegistry;
import org.apache.openjpa.enhance.PersistenceCapable;
@@ -70,7 +72,6 @@ import org.apache.openjpa.lib.util.Refer
import org.apache.openjpa.lib.util.ReferenceMap;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.meta.SequenceMetaData;
import org.apache.openjpa.meta.ValueMetaData;
@@ -88,7 +89,6 @@ import org.apache.openjpa.util.ObjectId;
import org.apache.openjpa.util.ObjectNotFoundException;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OptimisticException;
-import org.apache.openjpa.util.Proxy;
import org.apache.openjpa.util.RuntimeExceptionTranslator;
import org.apache.openjpa.util.StoreException;
import org.apache.openjpa.util.UnsupportedException;
@@ -1416,8 +1416,25 @@ public class BrokerImpl
releaseConn = _connRetainMode != CONN_RETAIN_ALWAYS;
if (rollback)
_store.rollback();
- else
+ else {
+ // and notify the query cache. notify in one batch to reduce synch
+ QueryCache queryCache = getConfiguration().
+ getDataCacheManagerInstance().getSystemQueryCache();
+ if (queryCache != null) {
+ Collection<Class<?>> pers = getPersistedTypes();
+ Collection<Class<?>> del = getDeletedTypes();
+ Collection<Class<?>> up = getUpdatedTypes();
+ int size = pers.size() + del.size() + up.size();
+ if (size > 0) {
+ Collection<Class<?>> types = new ArrayList<Class<?>>(size);
+ types.addAll(pers);
+ types.addAll(del);
+ types.addAll(up);
+ queryCache.onTypesChanged(new TypesChangedEvent(this, types));
+ }
+ }
_store.commit();
+ }
} else {
releaseConn = _connRetainMode == CONN_RETAIN_TRANS;
_store.rollbackOptimistic();
@@ -5039,4 +5056,19 @@ public class BrokerImpl
return null;
}
}
+
+ public boolean isCached(List<Object> oids) {
+ BitSet loaded = new BitSet(oids.size());
+ //check L1 cache first
+ for (int i = 0; i < oids.size(); i++) {
+ Object oid = oids.get(i);
+ if (_cache.getById(oid, false) != null) {
+ loaded.set(i);
+ }
+ }
+ if(loaded.cardinality()==oids.size()){
+ return true;
+ }
+ return _store.isCached(oids, loaded);
+ };
}
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java Tue Mar 30 03:43:20 2010
@@ -21,6 +21,7 @@ package org.apache.openjpa.kernel;
import java.util.BitSet;
import java.util.Collection;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -1463,4 +1464,8 @@ public class DelegatingBroker
public Object getConnectionFactory2() {
return _broker.getConnectionFactory2();
}
+
+ public boolean isCached(List<Object> oid) {
+ return _broker.isCached(oid);
+ }
}
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java Tue Mar 30 03:43:20 2010
@@ -20,6 +20,7 @@ package org.apache.openjpa.kernel;
import java.util.BitSet;
import java.util.Collection;
+import java.util.List;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
import org.apache.openjpa.meta.ClassMetaData;
@@ -199,4 +200,9 @@ public abstract class DelegatingStoreMan
public boolean cancelAll() {
return _store.cancelAll();
}
+
+ public boolean isCached(List<Object> oids, BitSet edata) {
+ return _store.isCached(oids, edata);
+ }
+
}
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java Tue Mar 30 03:43:20 2010
@@ -21,9 +21,11 @@ package org.apache.openjpa.kernel;
import java.util.BitSet;
import java.util.Collection;
import java.util.Iterator;
+import java.util.List;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.util.UserException;
/**
* Represents a set of managed objects and their environment.
@@ -111,8 +113,8 @@ public interface StoreContext {
public String getConnectionPassword();
/**
- * Return the cached instance for the given oid/object, or null if not
- * cached.
+ * Return the instance for the given oid/object , or null if not
+ * found in the L1 cache.
*
* @param oid the object's id
* @return the cached object, or null if not cached
@@ -490,4 +492,12 @@ public interface StoreContext {
* @return the NonJTA connection factory or null if connectionFactoryName is blank.
*/
public Object getConnectionFactory2();
+
+ /**
+ * Indicate whether the oid can be found in the StoreContext's L1 cache or in the StoreManager cache.
+ * @param oid List of ObjectIds for PersistenceCapables which may be found in memory.
+ * @return true if the oid is available in memory (cached) otherwise false.
+ * @since 2.0.0.
+ */
+ public boolean isCached(List<Object> oid);
}
Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java (original)
+++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java Tue Mar 30 03:43:20 2010
@@ -20,6 +20,7 @@ package org.apache.openjpa.kernel;
import java.util.BitSet;
import java.util.Collection;
+import java.util.List;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
import org.apache.openjpa.lib.util.Closeable;
@@ -99,6 +100,13 @@ public interface StoreManager
* if it does not.
*/
public boolean exists(OpenJPAStateManager sm, Object edata);
+
+ /**
+ * Verify that the given instance exists in the data store in memory; return false
+ * if it does not. When an object is found in memory the corresponding element of
+ * the BitSet is set to 1.
+ */
+ public boolean isCached(List<Object> oids, BitSet edata);
/**
* Update the version information in the given state manager to the
Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java (original)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java Tue Mar 30 03:43:20 2010
@@ -781,7 +781,8 @@ public abstract class CacheTest extends
Collection c = (Collection) q.execute();
iterate(c);
- assertInCache(q, Boolean.FALSE);
+ // Query results are no longer dependent on cacheability of an entity.
+ assertInCache(q, Boolean.TRUE);
}
finally {
close(broker);
@@ -801,7 +802,8 @@ public abstract class CacheTest extends
Collection c = (Collection) q.execute();
iterate(c);
- assertInCache(q, Boolean.FALSE);
+ // Query results are no longer dependent on cacheability of an entity.
+ assertInCache(q, Boolean.TRUE);
}
finally {
close(broker);
Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java (original)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java Tue Mar 30 03:43:20 2010
@@ -23,112 +23,104 @@ import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NamedQuery;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
import org.apache.openjpa.persistence.querycache.common.apps.Entity1;
import org.apache.openjpa.persistence.querycache.common.apps.Entity2;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
@NamedQuery(name = "setParam1",
- query = "SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-public class TestQueryCache extends AbstractTestCase {
+ query = "SELECT o FROM Entity1 o WHERE o.pk = :pk")
+public class TestQueryCache extends SQLListenerTestCase {
EntityManager em;
- public TestQueryCache(String name) {
- super(name, "");
- System.setProperty("cactus.contextURL",
- "http://localhost:9000/cachecactus");
- em = currentEntityManager();
- }
-
- /*public static Test suite()
- {
- ServletTestSuite suite = new ServletTestSuite();
- suite.addTestSuite(TestQueryCache.class);
- return suite;
- }*/
public void setUp() {
- System.setProperty("cactus.contextURL",
- "http://localhost:9000/cactuswebapp");
-
- //deleteAll(Entity2.class);
- deleteAll(Entity1.class);
-
- int instNum = 10;
-
- startTx(em);
-
+ super.setUp(
+ DROP_TABLES,
+ "openjpa.QueryCache", "true",
+ "openjpa.RemoteCommitProvider","sjvm",
+ Entity1.class,Entity2.class
+ // ,"openjpa.Log","SQL=trace"
+ );
+ em = emf.createEntityManager();
+
+ em.getTransaction().begin();
//create and persist multiple entity1 instances
- for (int i = 0; i < instNum; i++) {
+ for (int i = 0; i < 10; i++) {
Entity1 ent = new Entity1(i, "string" + i, i + 2);
Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
ent.setEntity2Field(ent2);
em.persist(ent);
}
-
- endTx(em);
- endEm(em);
+ em.getTransaction().commit();
}
+ public void testCachedQuery(){
+ em.createQuery("Select object(o) from Entity1 o").getResultList().get(0);
+ resetSQL();
+ em.createQuery("Select object(o) from Entity1 o").getResultList().get(0);
+ em.createQuery("Select object(o) from Entity1 o").getResultList().get(0);
+
+ assertEquals(0, getSQLCount());
+
+ }
public void testResultList() {
- em = currentEntityManager();
List list = em.createQuery("Select object(o) from Entity1 o")
.getResultList();
assertEquals(10, list.size());
- endEm(em);
}
public void testGetSingleList() {
- em = currentEntityManager();
+
String curr = 2 + "";
Entity1 ret = (Entity1) em
- .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
- .setParameter("pk", curr)
+ .createQuery("SELECT o FROM Entity1 o WHERE o.pk = :pk")
+ .setParameter("pk", Long.valueOf(curr))
.getSingleResult();
assertNotNull(ret);
assertEquals("string2", ret.getStringField());
assertEquals(4, ret.getIntField());
- endEm(em);
+
}
public void testExecuteUpdate() {
String curr = 2 + "";
String curr2 = 22 + "";
- em = currentEntityManager();
+
startTx(em);
Entity1 entity1 = (Entity1) em
- .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
- .setParameter("pk", curr)
+ .createQuery("SELECT o FROM Entity1 o WHERE o.pk = :pk")
+ .setParameter("pk", Long.valueOf(curr))
.getSingleResult();
- int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
- .setParameter("pk", curr)
+ int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk = :pk")
+ .setParameter("pk", Long.valueOf(curr))
.executeUpdate();
assertEquals(ret, 1);
// cascade remove doesn't remove the entity2
- int retTmp = em.createQuery("Delete FROM Entity2 o WHERE o.pk LIKE :pk")
+ int retTmp = em.createQuery("Delete FROM Entity2 o WHERE o.pk = :pk")
.setParameter("pk", entity1.getEntity2Field().getPk())
.executeUpdate();
- int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
- .setParameter("pk", curr2)
+ int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk = :pk")
+ .setParameter("pk", Long.valueOf(curr2))
.executeUpdate();
assertEquals(ret2, 0);
endTx(em);
- endEm(em);
+
}
public void testSetMaxResults() {
- em = currentEntityManager();
+
List l = em.createQuery("Select object(o) from Entity1 o")
.setMaxResults(5)
@@ -137,11 +129,11 @@ public class TestQueryCache extends Abst
assertNotNull(l);
assertEquals(5, l.size());
- endEm(em);
+
}
public void testSetFirstResults() {
- em = currentEntityManager();
+
List l = em.createQuery("Select object(o) from Entity1 o")
.setFirstResult(3)
@@ -153,37 +145,23 @@ public class TestQueryCache extends Abst
assertEquals("string3", ent.getStringField());
assertEquals(5, ent.getIntField());
- endEm(em);
- }
-
- // Tests Binding an argument to a named parameter.
- // pk, the named parameter --Not working yet--
- public void xxxtestSetParameter1() {
-
- em = currentEntityManager();
- String curr = 2 + "";
-
- List ret = em.createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
- .setParameter("pk", curr)
- .getResultList();
-
- assertNotNull(ret);
- assertEquals(1, ret.size());
- ret = em.createNamedQuery("setParam1")
- .setParameter("pk", curr)
- .getResultList();
-
- assertNotNull(ret);
- assertEquals(1, ret.size());
+ }
- endTx(em);
+ protected void startTx(EntityManager em) {
+ em.getTransaction().begin();
}
-
- @Override
- public String getPersistenceUnitName() {
- return "QueryCache";
+
+ protected boolean isActiveTx(EntityManager em) {
+ return em.getTransaction().isActive();
}
- //rest of the interface is tested by the CTS
+ protected void endTx(EntityManager em) {
+ if (em.getTransaction().isActive()) {
+ if (em.getTransaction().getRollbackOnly())
+ em.getTransaction().rollback();
+ else
+ em.getTransaction().commit();
+ }
+ }
}
Added: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java?rev=928968&view=auto
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java (added)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java Tue Mar 30 03:43:20 2010
@@ -0,0 +1,67 @@
+/*
+ * 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.relations;
+
+import java.util.Collection;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+
+@Entity
+public class PPerson {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private int id;
+
+ private String name;
+
+ @ManyToMany(fetch=FetchType.EAGER, mappedBy="people")
+ private Collection<PPhone> phones;
+
+ public int getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Collection<PPhone> getPhones() {
+ return phones;
+ }
+
+ public void setPhones(Collection<PPhone> phones) {
+ this.phones = phones;
+ }
+
+ @Override
+ public String toString() {
+ return "Person [id=" + id + ", number=" + name + "]";
+ }
+
+
+}
Propchange: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java?rev=928968&view=auto
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java (added)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java Tue Mar 30 03:43:20 2010
@@ -0,0 +1,65 @@
+/*
+ * 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.relations;
+
+import java.util.Collection;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+
+@Entity
+public class PPhone {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private int id;
+
+ private String number;
+
+ @ManyToMany(fetch=FetchType.EAGER)
+ private Collection<PPerson> people;
+
+ public int getId() {
+ return id;
+ }
+
+ public String getNumber() {
+ return number;
+ }
+
+ public void setNumber(String number) {
+ this.number = number;
+ }
+
+ public Collection<PPerson> getPeople() {
+ return people;
+ }
+
+ public void setPeople(Collection<PPerson> people) {
+ this.people = people;
+ }
+
+ @Override
+ public String toString() {
+ return "Phone [id=" + id + ", number=" + number + "]";
+ }
+}
Propchange: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java (original)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java Tue Mar 30 03:43:20 2010
@@ -18,6 +18,7 @@
*/
package org.apache.openjpa.persistence.relations;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -41,13 +42,18 @@ public class TestInverseEagerSQL
public int numCustomers = 1;
public int numOrdersPerCustomer = 4;
+
+ public int _nPeople = 3;
+ public int _nPhones = 3;
public void setUp() {
setUp(Customer.class, Customer.CustomerKey.class, Order.class,
EntityAInverseEager.class, EntityA1InverseEager.class,
EntityA2InverseEager.class, EntityBInverseEager.class,
EntityCInverseEager.class, EntityDInverseEager.class,
- Publisher.class, Magazine.class, DROP_TABLES);
+ Publisher.class, Magazine.class,
+ PPerson.class, PPhone.class,
+ DROP_TABLES);
// Not all databases support GenerationType.IDENTITY column(s)
if (!((JDBCConfiguration) emf.getConfiguration()).
@@ -132,6 +138,21 @@ public class TestInverseEagerSQL
magazine.setName("magagine"+i+"_"+p2.getName());
em.persist(magazine);
}
+
+ PPerson person;
+ PPhone phone;
+ for(int i =0; i < _nPeople; i++) {
+ person = new PPerson();
+ person.setPhones(new ArrayList<PPhone>());
+ em.persist(person);
+ for(int j = 0; j < _nPhones; j++) {
+ phone = new PPhone();
+ phone.setPeople(new ArrayList<PPerson>());
+ phone.getPeople().add(person);
+ person.getPhones().add(phone);
+ em.persist(phone);
+ }
+ }
em.flush();
em.getTransaction().commit();
@@ -255,8 +276,8 @@ public class TestInverseEagerSQL
// Not all databases support GenerationType.IDENTITY column(s)
if (!((JDBCConfiguration) emf.getConfiguration()).
getDBDictionaryInstance().supportsAutoAssign) {
- return;
- }
+ return;
+ }
sql.clear();
OpenJPAEntityManager em = emf.createEntityManager();
@@ -282,6 +303,36 @@ public class TestInverseEagerSQL
assertEquals(0, sql.size());
em.close();
}
+
+ public void testManyToManyEagerEagerInverseLazyQuery() {
+ // Not all databases support GenerationType.IDENTITY column(s)
+ if (!((JDBCConfiguration) emf.getConfiguration()).
+ getDBDictionaryInstance().supportsAutoAssign) {
+ return;
+ }
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ String query = "select p FROM PPerson p";
+ Query q = em.createQuery(query);
+ List list = q.getResultList();
+ assertEquals(_nPeople, list.size());
+ assertEquals(7, sql.size());
+
+ sql.clear();
+ em.clear();
+ for (int i = 0; i < list.size(); i++) {
+ PPerson p = (PPerson) list.get(i);
+ Collection<PPhone> phones = p.getPhones();
+ assertEquals(_nPhones, phones.size());
+ for(PPhone phone : p.getPhones()) {
+ assertNotNull(phone.getPeople());
+ assertTrue(phone.getPeople().contains(p));
+ }
+ }
+ assertEquals(0, sql.size());
+ em.close();
+ }
public void testTargetOrphanRemoval() {
// Not all databases support GenerationType.IDENTITY column(s)
Modified: openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java (original)
+++ openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java Tue Mar 30 03:43:20 2010
@@ -283,4 +283,8 @@ public class XMLStoreManager
}
return new ListResultObjectProvider(pcs);
}
+ public boolean isCached(List<Object> oids, BitSet edata) {
+ // XMLStoreManager does not cache oids.
+ return false;
+ }
}
Re: svn commit: r928968 - in /openjpa/branches/2.0.x: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-persistence-jdbc/src...
Posted by Donald Woods <dw...@apache.org>.
Rick, don't forget to merge these changes into trunk.
For future work, please use trunk before checking into 2.0.x.
-Donald
On 3/29/10 11:43 PM, curtisr7@apache.org wrote:
> Author: curtisr7
> Date: Tue Mar 30 03:43:20 2010
> New Revision: 928968
>
> URL: http://svn.apache.org/viewvc?rev=928968&view=rev
> Log:
> OPENAJPA-1603: Decouple the QueryCache from the DataCache. Code contributed by Mike Dick and Rick Curtis.
>
> Added:
> openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java (with props)
> openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java (with props)
> Modified:
> openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
> openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
> openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
> openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
> openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
> openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
>
> Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
> +++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Tue Mar 30 03:43:20 2010
> @@ -30,12 +30,15 @@ import java.util.Collection;
> import java.util.Collections;
> import java.util.HashSet;
> import java.util.Iterator;
> +import java.util.List;
> import java.util.Map;
> import java.util.Set;
>
> import javax.sql.DataSource;
>
> import org.apache.commons.lang.StringUtils;
> +import org.apache.openjpa.datacache.QueryCache;
> +import org.apache.openjpa.datacache.QueryCacheStoreQuery;
> import org.apache.openjpa.enhance.PersistenceCapable;
> import org.apache.openjpa.event.OrphanedKeyAction;
> import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
> @@ -295,6 +298,11 @@ public class JDBCStoreManager
> return exists(mapping, sm.getObjectId(), context);
> }
>
> + public boolean isCached(List<Object> oids, BitSet edata) {
> + // JDBCStoreManager doesn't store oids in memory.
> + return false;
> + }
> +
> private boolean exists(ClassMapping mapping, Object oid, Object context) {
> // add where conditions on base class to avoid joins if subclass
> // doesn't use oid as identifier
> @@ -455,8 +463,9 @@ public class JDBCStoreManager
> // Check if the owner has eagerly loaded ToMany relations.
> for (int i = 0; i < fms.length; i++) {
> if (res.getEager(fms[i]) != null) {
> - if (!fms[i].getElement().isTypePC())
> + if (!fms[i].getElement().isTypePC()) {
> continue;
> + }
> Object coll = owner.fetchObject(fms[i].getIndex());
> if (coll instanceof Map)
> coll = ((Map)coll).values();
> @@ -471,24 +480,23 @@ public class JDBCStoreManager
> for (Iterator<?> itr = ((Collection<?>) coll).iterator();
> itr.hasNext();) {
> PersistenceCapable pc = (PersistenceCapable) itr.next();
> -
> - if (pc == null)
> + if (pc == null) {
> continue;
> -
> - OpenJPAStateManager sm = (OpenJPAStateManager) pc.
> - pcGetStateManager();
> - FieldMapping[] fmd = ((ClassMapping) sm.getMetaData()).
> - getFieldMappings();
> + }
> + OpenJPAStateManager sm = (OpenJPAStateManager) pc.pcGetStateManager();
> + ClassMapping cm =
> + (ClassMapping) _conf.getMetaDataRepositoryInstance().getCachedMetaData(pc.getClass());
> + FieldMapping[] fmd = cm.getFieldMappings();
> for (int j = 0; j < fmd.length; j++) {
> - Object oid = sm.getIntermediate(fmd[j].getIndex());
> - // if oid was setIntermediate() previously
> - // and it is the same as the owner,
> - // then set the inverse relation
> - if (oid != null &&
> - oid.equals(owner.getObjectId())) {
> - sm.storeObject(fmd[j].getIndex(),
> - owner.getPersistenceCapable());
> - break;
> + // don't check the oids for basic fields.
> + if (fmd[j].isTypePC()) {
> + Object oid = sm.getIntermediate(fmd[j].getIndex());
> + // if oid was setIntermediate() previously and it is the same as the owner,generate
> + // then set the inverse relation
> + if (oid != null && oid.equals(owner.getObjectId())) {
> + sm.storeObject(fmd[j].getIndex(), owner.getPersistenceCapable());
> + break;
> + }
> }
> }
> }
> @@ -911,16 +919,33 @@ public class JDBCStoreManager
> return paged;
> }
>
> - public StoreQuery newQuery(String language) {
> + private StoreQuery newStoreQuery(String language) {
> ExpressionParser ep = QueryLanguages.parserForLanguage(language);
> - if (ep != null)
> + if (ep != null) {
> return new JDBCStoreQuery(this, ep);
> - if (QueryLanguages.LANG_SQL.equals(language))
> + }
> + if (QueryLanguages.LANG_SQL.equals(language)) {
> return new SQLStoreQuery(this);
> - if (QueryLanguages.LANG_PREPARED_SQL.equals(language))
> + }
> + if (QueryLanguages.LANG_PREPARED_SQL.equals(language)) {
> return new PreparedSQLStoreQuery(this);
> + }
> return null;
> }
> +
> + public StoreQuery newQuery(String language) {
> + StoreQuery sq = newStoreQuery(language);
> + if (sq == null || QueryLanguages.parserForLanguage(language) == null) {
> + return sq;
> + }
> +
> + QueryCache queryCache = _ctx.getConfiguration().getDataCacheManagerInstance().getSystemQueryCache();
> + if (queryCache == null) {
> + return sq;
> + }
> +
> + return new QueryCacheStoreQuery(sq, queryCache);
> + }
>
> public FetchConfiguration newFetchConfiguration() {
> return new JDBCFetchConfigurationImpl();
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java Tue Mar 30 03:43:20 2010
> @@ -57,7 +57,11 @@ public class DataCacheManagerImpl
>
> public void initialize(OpenJPAConfiguration conf, ObjectValue dataCache, ObjectValue queryCache) {
> _conf = conf;
> + _queryCache = (QueryCache) queryCache.instantiate(QueryCache.class, conf);
> + if (_queryCache != null)
> + _queryCache.initialize(this);
> _cache = (DataCache) dataCache.instantiate(DataCache.class, conf);
> +
> if (_cache == null)
> return;
>
> @@ -69,9 +73,7 @@ public class DataCacheManagerImpl
> _policy = conf.getCacheDistributionPolicyInstance();
>
> _cache.initialize(this);
> - _queryCache = (QueryCache) queryCache.instantiate(QueryCache.class, conf);
> - if (_queryCache != null)
> - _queryCache.initialize(this);
> +
> }
>
> public DataCache getSystemDataCache() {
> @@ -155,6 +157,7 @@ public class DataCacheManagerImpl
> _includedTypes = includedTypes;
> _excludedTypes = excludedTypes;
> }
> +
> /**
> * Affirms the given class is eligible to be cached according to the cache mode
> * and the cache enable flag on the given metadata.
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java Tue Mar 30 03:43:20 2010
> @@ -34,14 +34,11 @@ import org.apache.openjpa.kernel.DataCac
> import org.apache.openjpa.kernel.DataCacheStoreMode;
> import org.apache.openjpa.kernel.DelegatingStoreManager;
> import org.apache.openjpa.kernel.FetchConfiguration;
> -import org.apache.openjpa.kernel.FindCallbacks;
> import org.apache.openjpa.kernel.LockLevels;
> import org.apache.openjpa.kernel.OpenJPAStateManager;
> import org.apache.openjpa.kernel.PCState;
> -import org.apache.openjpa.kernel.QueryLanguages;
> import org.apache.openjpa.kernel.StoreContext;
> import org.apache.openjpa.kernel.StoreManager;
> -import org.apache.openjpa.kernel.StoreQuery;
> import org.apache.openjpa.meta.ClassMetaData;
> import org.apache.openjpa.meta.MetaDataRepository;
> import org.apache.openjpa.util.OpenJPAId;
> @@ -228,22 +225,6 @@ public class DataCacheStoreManager
> evictTypes(_ctx.getUpdatedTypes());
> }
>
> - // and notify the query cache. notify in one batch to reduce synch
> - QueryCache queryCache = _ctx.getConfiguration().
> - getDataCacheManagerInstance().getSystemQueryCache();
> - if (queryCache != null) {
> - Collection<Class<?>> pers = _ctx.getPersistedTypes();
> - Collection<Class<?>> del = _ctx.getDeletedTypes();
> - Collection<Class<?>> up = _ctx.getUpdatedTypes();
> - int size = pers.size() + del.size() + up.size();
> - if (size > 0) {
> - Collection<Class<?>> types = new ArrayList<Class<?>>(size);
> - types.addAll(pers);
> - types.addAll(del);
> - types.addAll(up);
> - queryCache.onTypesChanged(new TypesChangedEvent(this, types));
> - }
> - }
> }
> }
>
> @@ -292,12 +273,31 @@ public class DataCacheStoreManager
>
> public boolean exists(OpenJPAStateManager sm, Object edata) {
> DataCache cache = _mgr.selectCache(sm);
> - if (cache != null && !isLocking(null)
> - && cache.contains(sm.getObjectId()))
> + if (cache != null && !isLocking(null) && cache.contains(sm.getObjectId()))
> return true;
> return super.exists(sm, edata);
> }
>
> + public boolean isCached(List<Object> oids, BitSet edata) {
> + // If using partitioned cache, we were and still are broke.
> + DataCache cache = _mgr.getSystemDataCache();
> + if (cache != null && !isLocking(null)) {
> + // BitSet size is not consistent.
> + for(int i = 0; i < oids.size(); i++) {
> + Object oid = oids.get(i);
> + // Only check the cache if we haven't found the current oid.
> + if (edata.get(i) == false && cache.contains(oid)) {
> + edata.set(i);
> + }
> + }
> + if(edata.cardinality()==oids.size()){
> + return true;
> + }
> + }
> +
> + return super.isCached(oids, edata);
> + }
> +
> public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
> DataCache cache = _mgr.selectCache(sm);
> if (cache == null || sm.isEmbedded())
> @@ -660,22 +660,6 @@ public class DataCacheStoreManager
> .fireLocalStaleNotification(oid);
> }
>
> - public StoreQuery newQuery(String language) {
> - StoreQuery q = super.newQuery(language);
> -
> - // if the query can't be parsed or it's using a non-parsed language
> - // (one for which there is no ExpressionParser), we can't cache it.
> - if (q == null || QueryLanguages.parserForLanguage(language) == null)
> - return q;
> -
> - QueryCache queryCache = _ctx.getConfiguration().
> - getDataCacheManagerInstance().getSystemQueryCache();
> - if (queryCache == null)
> - return q;
> -
> - return new QueryCacheStoreQuery(q, queryCache);
> - }
> -
> /**
> * Create a new cacheable instance for the given state manager.
> */
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java Tue Mar 30 03:43:20 2010
> @@ -33,6 +33,7 @@ import java.util.TreeMap;
>
> import org.apache.commons.collections.map.LinkedMap;
> import org.apache.openjpa.datacache.AbstractQueryCache.EvictPolicy;
> +import org.apache.openjpa.kernel.DelegatingStoreManager;
> import org.apache.openjpa.kernel.FetchConfiguration;
> import org.apache.openjpa.kernel.LockLevels;
> import org.apache.openjpa.kernel.OpenJPAStateManager;
> @@ -122,6 +123,7 @@ public class QueryCacheStoreQuery
>
> // get the cached data
> QueryResult res = _cache.get(qk);
> +
> if (res == null)
> return null;
> if (res.isEmpty())
> @@ -153,24 +155,11 @@ public class QueryCacheStoreQuery
>
> int projs = getContext().getProjectionAliases().length;
> if (projs == 0) {
> - // make sure the data cache contains the oids for the query result;
> - // if it doesn't, then using the result could be slower than not
> - // using it because of the individual by-oid lookups
> - ClassMetaData meta = _repos.getMetaData(getContext().
> - getCandidateType(), _sctx.getClassLoader(), true);
> - if (meta.getDataCache() == null)
> + // We're only going to return the cached results if we have ALL results cached. This could be improved
> + // in the future to be a little more intelligent.
> + if (getContext().getStoreContext().isCached(res) == false) {
> return null;
> -
> - BitSet idxs = meta.getDataCache().containsAll(res);
> -
> - // eventually we should optimize this to figure out how many objects
> - // the cache is missing and if only a few do a bulk fetch for them
> - int len = idxs.length();
> - if (len < res.size())
> - return null;
> - for (int i = 0; i < len; i++)
> - if (!idxs.get(i))
> - return null;
> + }
> }
> return new CachedList(res, projs != 0, _sctx);
> }
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java Tue Mar 30 03:43:20 2010
> @@ -200,14 +200,11 @@ public class QueryKey
> // since the class change framework deals with least-derived types,
> // record the least-derived access path types
> meta = metas[i];
> - if (meta.getDataCache() != null)
> - accessPathClassNames.add(meta.getDescribedType().getName());
> - while (meta.getPCSuperclass() != null)
> - meta = meta.getPCSuperclassMetaData();
> -
> - // ensure that this metadata is cacheable
> - if (meta.getDataCache() == null)
> - return null;
> + accessPathClassNames.add(meta.getDescribedType().getName());
> + while (meta.getPCSuperclass() != null) {
> + meta = meta.getPCSuperclassMetaData();
> + }
> +
> accessPathClassNames.add(meta.getDescribedType().getName());
> }
>
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Tue Mar 30 03:43:20 2010
> @@ -51,6 +51,8 @@ import org.apache.commons.lang.StringUti
> import org.apache.openjpa.conf.Compatibility;
> import org.apache.openjpa.conf.OpenJPAConfiguration;
> import org.apache.openjpa.datacache.DataCache;
> +import org.apache.openjpa.datacache.QueryCache;
> +import org.apache.openjpa.datacache.TypesChangedEvent;
> import org.apache.openjpa.ee.ManagedRuntime;
> import org.apache.openjpa.enhance.PCRegistry;
> import org.apache.openjpa.enhance.PersistenceCapable;
> @@ -70,7 +72,6 @@ import org.apache.openjpa.lib.util.Refer
> import org.apache.openjpa.lib.util.ReferenceMap;
> import org.apache.openjpa.meta.ClassMetaData;
> import org.apache.openjpa.meta.FieldMetaData;
> -import org.apache.openjpa.meta.JavaTypes;
> import org.apache.openjpa.meta.MetaDataRepository;
> import org.apache.openjpa.meta.SequenceMetaData;
> import org.apache.openjpa.meta.ValueMetaData;
> @@ -88,7 +89,6 @@ import org.apache.openjpa.util.ObjectId;
> import org.apache.openjpa.util.ObjectNotFoundException;
> import org.apache.openjpa.util.OpenJPAException;
> import org.apache.openjpa.util.OptimisticException;
> -import org.apache.openjpa.util.Proxy;
> import org.apache.openjpa.util.RuntimeExceptionTranslator;
> import org.apache.openjpa.util.StoreException;
> import org.apache.openjpa.util.UnsupportedException;
> @@ -1416,8 +1416,25 @@ public class BrokerImpl
> releaseConn = _connRetainMode != CONN_RETAIN_ALWAYS;
> if (rollback)
> _store.rollback();
> - else
> + else {
> + // and notify the query cache. notify in one batch to reduce synch
> + QueryCache queryCache = getConfiguration().
> + getDataCacheManagerInstance().getSystemQueryCache();
> + if (queryCache != null) {
> + Collection<Class<?>> pers = getPersistedTypes();
> + Collection<Class<?>> del = getDeletedTypes();
> + Collection<Class<?>> up = getUpdatedTypes();
> + int size = pers.size() + del.size() + up.size();
> + if (size > 0) {
> + Collection<Class<?>> types = new ArrayList<Class<?>>(size);
> + types.addAll(pers);
> + types.addAll(del);
> + types.addAll(up);
> + queryCache.onTypesChanged(new TypesChangedEvent(this, types));
> + }
> + }
> _store.commit();
> + }
> } else {
> releaseConn = _connRetainMode == CONN_RETAIN_TRANS;
> _store.rollbackOptimistic();
> @@ -5039,4 +5056,19 @@ public class BrokerImpl
> return null;
> }
> }
> +
> + public boolean isCached(List<Object> oids) {
> + BitSet loaded = new BitSet(oids.size());
> + //check L1 cache first
> + for (int i = 0; i < oids.size(); i++) {
> + Object oid = oids.get(i);
> + if (_cache.getById(oid, false) != null) {
> + loaded.set(i);
> + }
> + }
> + if(loaded.cardinality()==oids.size()){
> + return true;
> + }
> + return _store.isCached(oids, loaded);
> + };
> }
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java Tue Mar 30 03:43:20 2010
> @@ -21,6 +21,7 @@ package org.apache.openjpa.kernel;
> import java.util.BitSet;
> import java.util.Collection;
> import java.util.Iterator;
> +import java.util.List;
> import java.util.Map;
> import java.util.Set;
>
> @@ -1463,4 +1464,8 @@ public class DelegatingBroker
> public Object getConnectionFactory2() {
> return _broker.getConnectionFactory2();
> }
> +
> + public boolean isCached(List<Object> oid) {
> + return _broker.isCached(oid);
> + }
> }
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java Tue Mar 30 03:43:20 2010
> @@ -20,6 +20,7 @@ package org.apache.openjpa.kernel;
>
> import java.util.BitSet;
> import java.util.Collection;
> +import java.util.List;
>
> import org.apache.openjpa.lib.rop.ResultObjectProvider;
> import org.apache.openjpa.meta.ClassMetaData;
> @@ -199,4 +200,9 @@ public abstract class DelegatingStoreMan
> public boolean cancelAll() {
> return _store.cancelAll();
> }
> +
> + public boolean isCached(List<Object> oids, BitSet edata) {
> + return _store.isCached(oids, edata);
> + }
> +
> }
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java Tue Mar 30 03:43:20 2010
> @@ -21,9 +21,11 @@ package org.apache.openjpa.kernel;
> import java.util.BitSet;
> import java.util.Collection;
> import java.util.Iterator;
> +import java.util.List;
>
> import org.apache.openjpa.conf.OpenJPAConfiguration;
> import org.apache.openjpa.meta.ValueMetaData;
> +import org.apache.openjpa.util.UserException;
>
> /**
> * Represents a set of managed objects and their environment.
> @@ -111,8 +113,8 @@ public interface StoreContext {
> public String getConnectionPassword();
>
> /**
> - * Return the cached instance for the given oid/object, or null if not
> - * cached.
> + * Return the instance for the given oid/object , or null if not
> + * found in the L1 cache.
> *
> * @param oid the object's id
> * @return the cached object, or null if not cached
> @@ -490,4 +492,12 @@ public interface StoreContext {
> * @return the NonJTA connection factory or null if connectionFactoryName is blank.
> */
> public Object getConnectionFactory2();
> +
> + /**
> + * Indicate whether the oid can be found in the StoreContext's L1 cache or in the StoreManager cache.
> + * @param oid List of ObjectIds for PersistenceCapables which may be found in memory.
> + * @return true if the oid is available in memory (cached) otherwise false.
> + * @since 2.0.0.
> + */
> + public boolean isCached(List<Object> oid);
> }
>
> Modified: openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java (original)
> +++ openjpa/branches/2.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java Tue Mar 30 03:43:20 2010
> @@ -20,6 +20,7 @@ package org.apache.openjpa.kernel;
>
> import java.util.BitSet;
> import java.util.Collection;
> +import java.util.List;
>
> import org.apache.openjpa.lib.rop.ResultObjectProvider;
> import org.apache.openjpa.lib.util.Closeable;
> @@ -99,6 +100,13 @@ public interface StoreManager
> * if it does not.
> */
> public boolean exists(OpenJPAStateManager sm, Object edata);
> +
> + /**
> + * Verify that the given instance exists in the data store in memory; return false
> + * if it does not. When an object is found in memory the corresponding element of
> + * the BitSet is set to 1.
> + */
> + public boolean isCached(List<Object> oids, BitSet edata);
>
> /**
> * Update the version information in the given state manager to the
>
> Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java (original)
> +++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java Tue Mar 30 03:43:20 2010
> @@ -781,7 +781,8 @@ public abstract class CacheTest extends
> Collection c = (Collection) q.execute();
> iterate(c);
>
> - assertInCache(q, Boolean.FALSE);
> + // Query results are no longer dependent on cacheability of an entity.
> + assertInCache(q, Boolean.TRUE);
> }
> finally {
> close(broker);
> @@ -801,7 +802,8 @@ public abstract class CacheTest extends
> Collection c = (Collection) q.execute();
> iterate(c);
>
> - assertInCache(q, Boolean.FALSE);
> + // Query results are no longer dependent on cacheability of an entity.
> + assertInCache(q, Boolean.TRUE);
> }
> finally {
> close(broker);
>
> Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java (original)
> +++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java Tue Mar 30 03:43:20 2010
> @@ -23,112 +23,104 @@ import java.util.List;
> import javax.persistence.EntityManager;
> import javax.persistence.NamedQuery;
>
> -import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
> import org.apache.openjpa.persistence.querycache.common.apps.Entity1;
> import org.apache.openjpa.persistence.querycache.common.apps.Entity2;
> +import org.apache.openjpa.persistence.test.SQLListenerTestCase;
>
> @NamedQuery(name = "setParam1",
> - query = "SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
> -public class TestQueryCache extends AbstractTestCase {
> + query = "SELECT o FROM Entity1 o WHERE o.pk = :pk")
> +public class TestQueryCache extends SQLListenerTestCase {
>
> EntityManager em;
>
> - public TestQueryCache(String name) {
> - super(name, "");
> - System.setProperty("cactus.contextURL",
> - "http://localhost:9000/cachecactus");
> - em = currentEntityManager();
> - }
> -
> - /*public static Test suite()
> - {
> - ServletTestSuite suite = new ServletTestSuite();
> - suite.addTestSuite(TestQueryCache.class);
> - return suite;
> - }*/
> public void setUp() {
> - System.setProperty("cactus.contextURL",
> - "http://localhost:9000/cactuswebapp");
> -
> - //deleteAll(Entity2.class);
> - deleteAll(Entity1.class);
> -
> - int instNum = 10;
> -
> - startTx(em);
> -
> + super.setUp(
> + DROP_TABLES,
> + "openjpa.QueryCache", "true",
> + "openjpa.RemoteCommitProvider","sjvm",
> + Entity1.class,Entity2.class
> + // ,"openjpa.Log","SQL=trace"
> + );
> + em = emf.createEntityManager();
> +
> + em.getTransaction().begin();
> //create and persist multiple entity1 instances
> - for (int i = 0; i < instNum; i++) {
> + for (int i = 0; i < 10; i++) {
> Entity1 ent = new Entity1(i, "string" + i, i + 2);
> Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
> ent.setEntity2Field(ent2);
> em.persist(ent);
> }
> -
> - endTx(em);
> - endEm(em);
> + em.getTransaction().commit();
> }
>
> + public void testCachedQuery(){
> + em.createQuery("Select object(o) from Entity1 o").getResultList().get(0);
> + resetSQL();
> + em.createQuery("Select object(o) from Entity1 o").getResultList().get(0);
> + em.createQuery("Select object(o) from Entity1 o").getResultList().get(0);
> +
> + assertEquals(0, getSQLCount());
> +
> + }
> public void testResultList() {
> - em = currentEntityManager();
> List list = em.createQuery("Select object(o) from Entity1 o")
> .getResultList();
>
> assertEquals(10, list.size());
>
> - endEm(em);
> }
>
> public void testGetSingleList() {
> - em = currentEntityManager();
> +
> String curr = 2 + "";
>
> Entity1 ret = (Entity1) em
> - .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
> - .setParameter("pk", curr)
> + .createQuery("SELECT o FROM Entity1 o WHERE o.pk = :pk")
> + .setParameter("pk", Long.valueOf(curr))
> .getSingleResult();
>
> assertNotNull(ret);
> assertEquals("string2", ret.getStringField());
> assertEquals(4, ret.getIntField());
>
> - endEm(em);
> +
> }
>
> public void testExecuteUpdate() {
> String curr = 2 + "";
> String curr2 = 22 + "";
>
> - em = currentEntityManager();
> +
> startTx(em);
>
> Entity1 entity1 = (Entity1) em
> - .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
> - .setParameter("pk", curr)
> + .createQuery("SELECT o FROM Entity1 o WHERE o.pk = :pk")
> + .setParameter("pk", Long.valueOf(curr))
> .getSingleResult();
>
> - int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
> - .setParameter("pk", curr)
> + int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk = :pk")
> + .setParameter("pk", Long.valueOf(curr))
> .executeUpdate();
> assertEquals(ret, 1);
>
> // cascade remove doesn't remove the entity2
> - int retTmp = em.createQuery("Delete FROM Entity2 o WHERE o.pk LIKE :pk")
> + int retTmp = em.createQuery("Delete FROM Entity2 o WHERE o.pk = :pk")
> .setParameter("pk", entity1.getEntity2Field().getPk())
> .executeUpdate();
>
> - int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
> - .setParameter("pk", curr2)
> + int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk = :pk")
> + .setParameter("pk", Long.valueOf(curr2))
> .executeUpdate();
>
> assertEquals(ret2, 0);
>
> endTx(em);
> - endEm(em);
> +
> }
>
> public void testSetMaxResults() {
> - em = currentEntityManager();
> +
>
> List l = em.createQuery("Select object(o) from Entity1 o")
> .setMaxResults(5)
> @@ -137,11 +129,11 @@ public class TestQueryCache extends Abst
> assertNotNull(l);
> assertEquals(5, l.size());
>
> - endEm(em);
> +
> }
>
> public void testSetFirstResults() {
> - em = currentEntityManager();
> +
>
> List l = em.createQuery("Select object(o) from Entity1 o")
> .setFirstResult(3)
> @@ -153,37 +145,23 @@ public class TestQueryCache extends Abst
> assertEquals("string3", ent.getStringField());
> assertEquals(5, ent.getIntField());
>
> - endEm(em);
> - }
> -
> - // Tests Binding an argument to a named parameter.
> - // pk, the named parameter --Not working yet--
> - public void xxxtestSetParameter1() {
> -
> - em = currentEntityManager();
> - String curr = 2 + "";
> -
> - List ret = em.createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
> - .setParameter("pk", curr)
> - .getResultList();
> -
> - assertNotNull(ret);
> - assertEquals(1, ret.size());
>
> - ret = em.createNamedQuery("setParam1")
> - .setParameter("pk", curr)
> - .getResultList();
> -
> - assertNotNull(ret);
> - assertEquals(1, ret.size());
> + }
>
> - endTx(em);
> + protected void startTx(EntityManager em) {
> + em.getTransaction().begin();
> }
> -
> - @Override
> - public String getPersistenceUnitName() {
> - return "QueryCache";
> +
> + protected boolean isActiveTx(EntityManager em) {
> + return em.getTransaction().isActive();
> }
>
> - //rest of the interface is tested by the CTS
> + protected void endTx(EntityManager em) {
> + if (em.getTransaction().isActive()) {
> + if (em.getTransaction().getRollbackOnly())
> + em.getTransaction().rollback();
> + else
> + em.getTransaction().commit();
> + }
> + }
> }
>
> Added: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java?rev=928968&view=auto
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java (added)
> +++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java Tue Mar 30 03:43:20 2010
> @@ -0,0 +1,67 @@
> +/*
> + * 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.relations;
> +
> +import java.util.Collection;
> +
> +import javax.persistence.Entity;
> +import javax.persistence.FetchType;
> +import javax.persistence.GeneratedValue;
> +import javax.persistence.GenerationType;
> +import javax.persistence.Id;
> +import javax.persistence.ManyToMany;
> +
> +@Entity
> +public class PPerson {
> + @Id
> + @GeneratedValue(strategy = GenerationType.IDENTITY)
> + private int id;
> +
> + private String name;
> +
> + @ManyToMany(fetch=FetchType.EAGER, mappedBy="people")
> + private Collection<PPhone> phones;
> +
> + public int getId() {
> + return id;
> + }
> +
> + public String getName() {
> + return name;
> + }
> +
> + public void setName(String name) {
> + this.name = name;
> + }
> +
> + public Collection<PPhone> getPhones() {
> + return phones;
> + }
> +
> + public void setPhones(Collection<PPhone> phones) {
> + this.phones = phones;
> + }
> +
> + @Override
> + public String toString() {
> + return "Person [id=" + id + ", number=" + name + "]";
> + }
> +
> +
> +}
>
> Propchange: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Added: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java?rev=928968&view=auto
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java (added)
> +++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java Tue Mar 30 03:43:20 2010
> @@ -0,0 +1,65 @@
> +/*
> + * 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.relations;
> +
> +import java.util.Collection;
> +
> +import javax.persistence.Entity;
> +import javax.persistence.FetchType;
> +import javax.persistence.GeneratedValue;
> +import javax.persistence.GenerationType;
> +import javax.persistence.Id;
> +import javax.persistence.ManyToMany;
> +
> +@Entity
> +public class PPhone {
> + @Id
> + @GeneratedValue(strategy = GenerationType.IDENTITY)
> + private int id;
> +
> + private String number;
> +
> + @ManyToMany(fetch=FetchType.EAGER)
> + private Collection<PPerson> people;
> +
> + public int getId() {
> + return id;
> + }
> +
> + public String getNumber() {
> + return number;
> + }
> +
> + public void setNumber(String number) {
> + this.number = number;
> + }
> +
> + public Collection<PPerson> getPeople() {
> + return people;
> + }
> +
> + public void setPeople(Collection<PPerson> people) {
> + this.people = people;
> + }
> +
> + @Override
> + public String toString() {
> + return "Phone [id=" + id + ", number=" + number + "]";
> + }
> +}
>
> Propchange: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java (original)
> +++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java Tue Mar 30 03:43:20 2010
> @@ -18,6 +18,7 @@
> */
> package org.apache.openjpa.persistence.relations;
>
> +import java.util.ArrayList;
> import java.util.Collection;
> import java.util.Iterator;
> import java.util.List;
> @@ -41,13 +42,18 @@ public class TestInverseEagerSQL
>
> public int numCustomers = 1;
> public int numOrdersPerCustomer = 4;
> +
> + public int _nPeople = 3;
> + public int _nPhones = 3;
>
> public void setUp() {
> setUp(Customer.class, Customer.CustomerKey.class, Order.class,
> EntityAInverseEager.class, EntityA1InverseEager.class,
> EntityA2InverseEager.class, EntityBInverseEager.class,
> EntityCInverseEager.class, EntityDInverseEager.class,
> - Publisher.class, Magazine.class, DROP_TABLES);
> + Publisher.class, Magazine.class,
> + PPerson.class, PPhone.class,
> + DROP_TABLES);
>
> // Not all databases support GenerationType.IDENTITY column(s)
> if (!((JDBCConfiguration) emf.getConfiguration()).
> @@ -132,6 +138,21 @@ public class TestInverseEagerSQL
> magazine.setName("magagine"+i+"_"+p2.getName());
> em.persist(magazine);
> }
> +
> + PPerson person;
> + PPhone phone;
> + for(int i =0; i < _nPeople; i++) {
> + person = new PPerson();
> + person.setPhones(new ArrayList<PPhone>());
> + em.persist(person);
> + for(int j = 0; j < _nPhones; j++) {
> + phone = new PPhone();
> + phone.setPeople(new ArrayList<PPerson>());
> + phone.getPeople().add(person);
> + person.getPhones().add(phone);
> + em.persist(phone);
> + }
> + }
>
> em.flush();
> em.getTransaction().commit();
> @@ -255,8 +276,8 @@ public class TestInverseEagerSQL
> // Not all databases support GenerationType.IDENTITY column(s)
> if (!((JDBCConfiguration) emf.getConfiguration()).
> getDBDictionaryInstance().supportsAutoAssign) {
> - return;
> - }
> + return;
> + }
> sql.clear();
>
> OpenJPAEntityManager em = emf.createEntityManager();
> @@ -282,6 +303,36 @@ public class TestInverseEagerSQL
> assertEquals(0, sql.size());
> em.close();
> }
> +
> + public void testManyToManyEagerEagerInverseLazyQuery() {
> + // Not all databases support GenerationType.IDENTITY column(s)
> + if (!((JDBCConfiguration) emf.getConfiguration()).
> + getDBDictionaryInstance().supportsAutoAssign) {
> + return;
> + }
> + sql.clear();
> +
> + OpenJPAEntityManager em = emf.createEntityManager();
> + String query = "select p FROM PPerson p";
> + Query q = em.createQuery(query);
> + List list = q.getResultList();
> + assertEquals(_nPeople, list.size());
> + assertEquals(7, sql.size());
> +
> + sql.clear();
> + em.clear();
> + for (int i = 0; i < list.size(); i++) {
> + PPerson p = (PPerson) list.get(i);
> + Collection<PPhone> phones = p.getPhones();
> + assertEquals(_nPhones, phones.size());
> + for(PPhone phone : p.getPhones()) {
> + assertNotNull(phone.getPeople());
> + assertTrue(phone.getPeople().contains(p));
> + }
> + }
> + assertEquals(0, sql.size());
> + em.close();
> + }
>
> public void testTargetOrphanRemoval() {
> // Not all databases support GenerationType.IDENTITY column(s)
>
> Modified: openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
> URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java?rev=928968&r1=928967&r2=928968&view=diff
> ==============================================================================
> --- openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java (original)
> +++ openjpa/branches/2.0.x/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java Tue Mar 30 03:43:20 2010
> @@ -283,4 +283,8 @@ public class XMLStoreManager
> }
> return new ListResultObjectProvider(pcs);
> }
> + public boolean isCached(List<Object> oids, BitSet edata) {
> + // XMLStoreManager does not cache oids.
> + return false;
> + }
> }
>
>
>