Author: mikedd
Date: Tue Mar 30 20:42:29 2010
New Revision: 929266

URL: http://svn.apache.org/viewvc?rev=929266&view=rev
Log:
OPENJPA-1603: 
Decouple the QueryCache from the DataCache. Code contributed by Mike Dick and 
Rick Curtis.

Added:
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
   (with props)
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
   (with props)
Modified:
    
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
    
openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java

Modified: 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
 (original)
+++ 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/querycache/TestQueryCache.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java?rev=929266&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPerson.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java?rev=929266&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/PPhone.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
 Tue Mar 30 20:42:29 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/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java?rev=929266&r1=929265&r2=929266&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
 (original)
+++ 
openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
 Tue Mar 30 20:42:29 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;
+    }
 }


Reply via email to