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, curti...@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; > + } > } > > >