openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r790676 [1/2] - in /openjpa/trunk: 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-kernel/src/main/java/or...
Date Thu, 02 Jul 2009 16:57:18 GMT
Author: ppoddar
Date: Thu Jul  2 16:57:17 2009
New Revision: 790676

URL: http://svn.apache.org/viewvc?rev=790676&view=rev
Log:
OPENJPA-703: Expand type of queries that can be cached especially with various projection terms. Refactor testing of PreparedQueryCache.

Added:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedProjectionResultObjectProvider.java   (with props)
Removed:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestEagerQueries.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestParameterProcessing.java
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderCacheImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQueryCache.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryStatistics.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/QueryExpressions.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Address.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Book.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/CD.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Company.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Department.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Employee.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Merchandise.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Person.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestFinderCache.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCache.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderCacheImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderCacheImpl.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderCacheImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderCacheImpl.java Thu Jul  2 16:57:17 2009
@@ -120,7 +120,7 @@
             return null;
         FinderQuery<ClassMapping, SelectExecutor, Result> result = 
             _delegate.get(mapping);
-        _stats.recordExecution(mapping, result != null);
+        _stats.recordExecution(mapping);
         return result;
     }
     

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java Thu Jul  2 16:57:17 2009
@@ -170,8 +170,10 @@
         long end = (dict.supportsSelectEndIndex) ? range.end : Long.MAX_VALUE;
 
         QueryExpressionsState[] states = new QueryExpressionsState[exps.length];
-        for (int i = 0; i < states.length; i++)
+        for (int i = 0; i < states.length; i++) {
             states[i] = new QueryExpressionsState();
+            exps[i].state = states[i];
+        }
         ExpContext ctx = new ExpContext(_store, params, fetch);
 
         // add selects with populate WHERE conditions to list

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedProjectionResultObjectProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedProjectionResultObjectProvider.java?rev=790676&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedProjectionResultObjectProvider.java (added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedProjectionResultObjectProvider.java Thu Jul  2 16:57:17 2009
@@ -0,0 +1,57 @@
+/*
+ * 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.jdbc.kernel;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.exps.ExpContext;
+import org.apache.openjpa.jdbc.kernel.exps.QueryExpressionsState;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
+
+/**
+ * Object provider implementation wrapped around a projection select that has been executed earlier.
+ *
+ * @author Pinaki Poddar
+ */
+class PreparedProjectionResultObjectProvider
+    extends ProjectionResultObjectProvider {
+
+    public PreparedProjectionResultObjectProvider(SelectExecutor sel, 
+        QueryExpressions exps, QueryExpressionsState state, ExpContext ctx, Result res) {
+        super(sel, exps, state, ctx);
+        _res = res;
+    }
+
+    public PreparedProjectionResultObjectProvider(SelectExecutor sel, 
+        QueryExpressions[] exps, QueryExpressionsState[] state, ExpContext ctx, Result res){
+        super(sel, exps, state, ctx);
+        _res = res;
+    }
+
+    public Result getResult() {
+        return _res;
+    }
+    
+    public void open() throws SQLException {
+        // do nothing
+    }
+
+}

Propchange: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedProjectionResultObjectProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java Thu Jul  2 16:57:17 2009
@@ -330,6 +330,11 @@
         Object result = fetch.getHint(hint);
         return result != null && "true".equalsIgnoreCase(result.toString());
     }
+    
+    public void clear() {
+        _delegate.clear();
+        _stats.clear();
+    }
         
 	//-------------------------------------------------------
 	// Configurable contract

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java Thu Jul  2 16:57:17 2009
@@ -39,6 +39,8 @@
 import org.apache.openjpa.kernel.Query;
 import org.apache.openjpa.kernel.QueryImpl;
 import org.apache.openjpa.kernel.QueryLanguages;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.lib.rop.ResultList;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.util.ImplHelper;
@@ -47,6 +49,9 @@
 
 /**
  * Implements {@link PreparedQuery} for SQL queries.
+ * PreparedQuery holds the post-compilation and post-execution state of a kernel Query.
+ * The post-execution internal state of a query is appended as a <em>user object</em>
+ * to the user-visible result to maintain the API contract. 
  * 
  * @author Pinaki Poddar
  *
@@ -61,11 +66,12 @@
     
     // Post-compilation state of an executable query, populated on construction
     private Class<?> _candidate;
-    private Class<?>[] _resultClass;
-    private ClassMapping _resultMapping;
     private boolean _subclasses;
-    private boolean _isProjection;
     
+    // post-execution state of a query
+    private QueryExpressions[] _exps;
+    private Class<?>[] _projTypes;
+
     // Position of the user defined parameters in the _params list
     private Map<Object, int[]>    _userParamPositions;
     private Map<Integer, Object> _template;
@@ -94,9 +100,6 @@
         if (compiled != null) {
             _candidate    = compiled.getCandidateType();
             _subclasses   = compiled.hasSubclasses();
-            _isProjection = compiled.getProjectionAliases().length > 0;
-            if (_isProjection)
-                _resultClass  = compiled.getProjectionTypes();
         }
     }
     
@@ -128,17 +131,21 @@
         return _initialized;
     }
     
+    public QueryExpressions[] getQueryExpressions() {
+        return _exps;
+    }
+    
+    public Class[] getProjectionTypes() {
+        return _projTypes;
+    }
+    
     /**
      * Pours the post-compilation state held by this receiver to the given
      * query.
      */
     public void setInto(Query q) {
     	q.setQuery(_id);
-        if (!_isProjection)
-            q.setCandidateType(_candidate, _subclasses);
-        if (_resultMapping == null &&
-            _resultClass != null && _resultClass.length == 1)
-            q.setResultType(_resultClass[0]);
+        q.setCandidateType(_candidate, _subclasses);
     }
 
     /**
@@ -158,21 +165,6 @@
         select = extractImplementation(selector);
         if (select == null)
             return false;
-        if (_resultClass != null) {
-            // uncachable queries:
-            //   query not returning the candidate entity class type
-            //   query returing embeddable class type
-            //   query returning more than one entity class types
-            for (int i = 0; i < _resultClass.length; i++) {
-                _resultMapping = (ClassMapping) select.getConfiguration().
-                    getMetaDataRepositoryInstance().getMetaData(_resultClass[i],
-                    getClass().getClassLoader(), false);
-                if (_resultMapping != null && 
-                    (_resultClass[i] != _candidate ||
-                    _resultMapping.isEmbeddedOnly() || _resultClass.length > 1))
-                    return false;
-            }
-        }
         SQLBuffer buffer = selector.getSQL();
         if (buffer == null)
             return false;
@@ -185,16 +177,29 @@
     }
     
     /**
-     * Extract the underlying SelectExecutor from the given argument, if 
-     * possible.
+     * Extract the underlying SelectExecutor from the given argument, if possible.
      */
     private SelectExecutor extractSelectExecutor(Object result) {
         if (result instanceof ResultList == false)
             return null;
-        Object provider = ((ResultList)result).getUserObject();
+        Object userObject = ((ResultList<?>)result).getUserObject();
+        if (userObject == null || !userObject.getClass().isArray() || ((Object[])userObject).length != 2)
+            return null;
+        Object provider = ((Object[])userObject)[0];
+        Object executor = ((Object[])userObject)[1];
+        if (executor instanceof StoreQuery.Executor == false)
+            return null;
+        _exps = ((StoreQuery.Executor)executor).getQueryExpressions();
+        if (_exps[0].projections.length == 0) {
+            _projTypes = StoreQuery.EMPTY_CLASSES;
+        } else {
+            _projTypes = new Class[_exps[0].projections.length];
+            for (int i = 0; i < _exps[0].projections.length; i++) {
+                _projTypes[i] = _exps[0].projections[i].getType();
+            }
+        }
         if (provider instanceof QueryImpl.PackingResultObjectProvider) {
-            provider = ((QueryImpl.PackingResultObjectProvider)provider)
-                .getDelegate();
+            provider = ((QueryImpl.PackingResultObjectProvider)provider).getDelegate();
         }
         if (provider instanceof SelectResultObjectProvider) {
             return ((SelectResultObjectProvider)provider).getSelect();

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java Thu Jul  2 16:57:17 2009
@@ -24,7 +24,8 @@
 import java.sql.SQLException;
 import java.util.Map;
 
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.kernel.exps.ExpContext;
+import org.apache.openjpa.jdbc.kernel.exps.QueryExpressionsState;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.Result;
@@ -33,6 +34,8 @@
 import org.apache.openjpa.jdbc.sql.SQLExceptions;
 import org.apache.openjpa.jdbc.sql.SelectImpl;
 import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.ExpressionStoreQuery.AbstractExpressionExecutor;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
 import org.apache.openjpa.meta.ClassMetaData;
@@ -44,6 +47,7 @@
  * @author Pinaki Poddar
  *
  */
+@SuppressWarnings("serial")
 public class PreparedSQLStoreQuery extends SQLStoreQuery {
     private PreparedQueryImpl _cached;
     public PreparedSQLStoreQuery(JDBCStore store) {
@@ -67,20 +71,29 @@
         return _cached;
     }
 
-    
-    public static class PreparedSQLExecutor extends AbstractExecutor {
+    /**
+     * Executor of a prepared query uses the QueryExpressions of the original query
+     * available via the PreparedQuery.
+     *
+     */
+    public static class PreparedSQLExecutor extends AbstractExpressionExecutor {
         private final ClassMetaData _meta;
-        public PreparedSQLExecutor(PreparedSQLStoreQuery q, 
-            ClassMetaData candidate) {
+        private final PreparedSQLStoreQuery _query;
+        
+        public PreparedSQLExecutor(PreparedSQLStoreQuery q, ClassMetaData candidate) {
             _meta = candidate;
+            _query = q;
         }
-               
-        public int getOperation(StoreQuery q) {
-            return OP_SELECT;
+        
+        public QueryExpressions[] getQueryExpressions() {
+            return _query.getPreparedQuery().getQueryExpressions();
+        }
+        
+        public Class[] getProjectionTypes() {
+            return _query.getPreparedQuery().getProjectionTypes();
         }
 
-        public ResultObjectProvider executeQuery(StoreQuery q,
-            Object[] params, Range range) {
+        public ResultObjectProvider executeQuery(StoreQuery q, Object[] params, Range range) {
             PreparedSQLStoreQuery psq = (PreparedSQLStoreQuery) q;
             PreparedQueryImpl pq = psq.getPreparedQuery();
             JDBCStore store = psq.getStore();
@@ -88,33 +101,36 @@
 
             SQLBuffer buf = new SQLBuffer(dict).append(pq.getTargetQuery());
             Connection conn = store.getConnection();
-            JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)
-                q.getContext().getFetchConfiguration();
+            JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)q.getContext().getFetchConfiguration();
 
             ResultObjectProvider rop;
             PreparedStatement stmnt = null;
             try {
-                stmnt = !range.lrs
-                    ? buf.prepareStatement(conn)
-                    : buf.prepareStatement(conn, fetch, -1, -1);
+                stmnt = !range.lrs ? buf.prepareStatement(conn) : buf.prepareStatement(conn, fetch, -1, -1);
 
                 int index = 0;
-                for (int i = 0; i < params.length; i++)
+                for (int i = 0; i < params.length; i++) {
                     dict.setUnknown(stmnt, ++index, params[i], null);
-
+                }
                 dict.setTimeouts(stmnt, fetch, false);
 
                 ResultSet rs = stmnt.executeQuery();
                 
                 SelectImpl cachedSelect = pq.getSelect();
-                Result res = cachedSelect.getEagerResult(conn, stmnt, rs, 
-                    store, fetch, false, null);
-                if (q.getContext().getCandidateType() != null)
+                Result res = cachedSelect.getEagerResult(conn, stmnt, rs, store, fetch, false, null);
+                
+                if (getQueryExpressions()[0].projections.length > 0) {
+                    ExpContext ctx = new ExpContext(store, params, fetch);
+                    QueryExpressionsState state = (QueryExpressionsState)getQueryExpressions()[0].state;
+                    rop = new PreparedProjectionResultObjectProvider(cachedSelect, getQueryExpressions(), 
+                            new QueryExpressionsState[]{state}, ctx, res);
+                } else if (q.getContext().getCandidateType() != null) {
                     rop = new PreparedResultObjectProvider(cachedSelect, 
                         (ClassMapping) _meta, store, fetch, res);
-                else
+                } else {
                     rop = new SQLProjectionResultObjectProvider(store, fetch,
                         (ResultSetResult)res, q.getContext().getResultType());
+                }
             } catch (SQLException se) {
                 if (stmnt != null)
                     try { stmnt.close(); } catch (SQLException se2) {}
@@ -133,8 +149,7 @@
          * The given userParams is already re-parameterized, so this method have
          * to merely copy the given Map values.
          * 
-         * @see PreparedQueryImpl#reparametrize(Map,
-         * org.apache.openjpa.kernel.Broker)
+         * @see PreparedQueryImpl#reparametrize(Map, org.apache.openjpa.kernel.Broker)
          */
         public Object[] toParameterArray(StoreQuery q, Map userParams) {
             Object[] array = new Object[userParams.size()];

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java Thu Jul  2 16:57:17 2009
@@ -27,14 +27,11 @@
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.meta.MappingRepository;
 import org.apache.openjpa.jdbc.meta.QueryResultMapping;

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java Thu Jul  2 16:57:17 2009
@@ -76,7 +76,8 @@
     public static final String ACTION_ADD = "add";
     public static final String ACTION_GET = "get";
     public static final String ACTION_SET = "set";
-
+    public static final String DEFAULT_TABLE = "OPENJPA_SEQUENCE_TABLE";
+    
     private static final Localizer _loc = Localizer.forPackage
         (TableJDBCSeq.class);
 
@@ -87,7 +88,7 @@
     private final HashMap<ClassMapping, Status> _stat =
         new HashMap<ClassMapping, Status>();
 
-    private String _table = "OPENJPA_SEQUENCE_TABLE";
+    private String _table = DEFAULT_TABLE;
     private String _seqColumnName = "SEQUENCE_VALUE";
     private String _pkColumnName = "ID";
     private String[] _uniqueColumnNames;

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=790676&r1=790675&r2=790676&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 Thu Jul  2 16:57:17 2009
@@ -41,6 +41,7 @@
 import org.apache.openjpa.kernel.StoreQuery;
 import org.apache.openjpa.kernel.exps.AggregateListener;
 import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.lib.rop.ListResultObjectProvider;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
 import org.apache.openjpa.meta.ClassMetaData;
@@ -350,6 +351,10 @@
             else
                 return rop;
         }
+        
+        public QueryExpressions[] getQueryExpressions() {
+            return _ex.getQueryExpressions();
+        }
 
         /**
          * Clear the cached queries associated with the access path

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java Thu Jul  2 16:57:17 2009
@@ -23,6 +23,7 @@
 import org.apache.commons.collections.map.LinkedMap;
 import org.apache.openjpa.kernel.exps.AggregateListener;
 import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.UnsupportedException;
@@ -131,6 +132,11 @@
         public void validate(StoreQuery q) {
         }
 
+
+        public QueryExpressions[] getQueryExpressions() {
+            return null;
+        }
+        
         public void getRange(StoreQuery q, Object[] params, Range range) {
         }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java Thu Jul  2 16:57:17 2009
@@ -287,11 +287,6 @@
         implements Executor {
 
         /**
-         * Return the parsed query expressions for our candidate types.
-         */
-        protected abstract QueryExpressions[] getQueryExpressions();
-
-        /**
          * Return the query expressions for one candidate type, or die if none.
          */
         private QueryExpressions assertQueryExpression() {
@@ -370,6 +365,10 @@
         public final String[] getProjectionAliases(StoreQuery q) {
             return assertQueryExpression().projectionAliases;
         }
+        
+        public Class[] getProjectionTypes(StoreQuery q) {
+            return null;
+        }
 
         public final int getOperation(StoreQuery q) {
             return assertQueryExpression().operation;
@@ -574,7 +573,7 @@
             }
         }
 
-        protected QueryExpressions[] getQueryExpressions() {
+        public QueryExpressions[] getQueryExpressions() {
             return _exps;
         }
 
@@ -735,7 +734,7 @@
             }
         }
 
-        protected QueryExpressions[] getQueryExpressions() {
+        public QueryExpressions[] getQueryExpressions() {
             return _exps;
         }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQueryCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQueryCache.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQueryCache.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQueryCache.java Thu Jul  2 16:57:17 2009
@@ -187,6 +187,11 @@
 	public void removeExclusionPattern(String pattern);
 	
 	/**
+	 * Clears all cached queries.
+	 */
+	public void clear();
+	
+	/**
 	 * Gets the simple statistics for executed queries.
 	 */
 	public QueryStatistics<String> getStatistics();

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java Thu Jul  2 16:57:17 2009
@@ -41,6 +41,7 @@
 import org.apache.openjpa.kernel.exps.Literal;
 import org.apache.openjpa.kernel.exps.Parameter;
 import org.apache.openjpa.kernel.exps.Path;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.kernel.exps.Val;
 import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
 import org.apache.openjpa.lib.log.Log;
@@ -1230,7 +1231,7 @@
         boolean lrs = range.lrs && !ex.isAggregate(q) && !ex.hasGrouping(q);
         ResultList res = (!detach && lrs) ? _fc.newResultList(rop)
             : new EagerResultList(rop);
-        res.setUserObject(rop);
+        res.setUserObject(new Object[]{rop,ex});
         _resultLists.add(decorateResultList(res));
         return res;
     }
@@ -1825,6 +1826,10 @@
         public MergedExecutor(StoreQuery.Executor[] executors) {
             _executors = executors;
         }
+        
+        public QueryExpressions[] getQueryExpressions() {
+            return _executors[0].getQueryExpressions();
+        }
 
         public ResultObjectProvider executeQuery(StoreQuery q,
             Object[] params, StoreQuery.Range range) {

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryStatistics.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryStatistics.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryStatistics.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryStatistics.java Thu Jul  2 16:57:17 2009
@@ -40,10 +40,9 @@
 public interface QueryStatistics<T> extends Serializable {
 	
 	/**
-	 * Record that the given query has been executed. The boolean parameter
-	 * designates whether the executed query is a cached version.  
+	 * Record that the given query has been executed. 
 	 */
-	void recordExecution(T query, boolean cached);
+	void recordExecution(T query);
 		
 	/**
 	 * Gets number of total query execution since last reset.
@@ -98,11 +97,16 @@
 	public Date start();
 
 	/**
-	 * Clears all accumulated statistics.
+	 * Clears all  statistics accumulated since last reset.
 	 */
 	public void reset();
 	
 	/**
+	 * Clears all statistics accumulated since start.
+	 */
+	public void clear();
+	
+	/**
 	 * Dumps on the given output stream.
 	 */
 	public void dump(PrintStream out);
@@ -113,6 +117,9 @@
 	 */
 	public static class Default<T> implements QueryStatistics<T> {
 		private static final int ARRAY_SIZE = 2;
+        private static final int READ  = 0;
+        private static final int HIT   = 1;
+        
 		private long[] astat = new long[ARRAY_SIZE];
 		private long[] stat  = new long[ARRAY_SIZE];
 		private Map<T, long[]> stats  = new HashMap<T, long[]>();
@@ -120,9 +127,6 @@
 		private Date start = new Date();
 		private Date since = start;
 
-		private static final int READ  = 0;
-		private static final int HIT   = 1;
-
 		public long getExecutionCount() {
 			return stat[READ];
 		}
@@ -173,6 +177,16 @@
 			stats.clear();
 			since = new Date();
 		}
+		
+	    public void clear() {
+	       astat = new long[ARRAY_SIZE];
+	       stat  = new long[ARRAY_SIZE];
+	       stats = new HashMap<T, long[]>();
+	       astats = new HashMap<T, long[]>();
+	       start  = new Date();
+	       since  = start;
+	    }
+
 
 		private void addSample(T query, int index) {
 			stat[index]++;
@@ -190,7 +204,8 @@
 			target.put(query, row);
 		}
 		
-		public void recordExecution(T query, boolean cached) {
+		public void recordExecution(T query) {
+		    boolean cached = (astats.containsKey(query));
 			addSample(query, READ);
 			if (cached)
 				addSample(query, HIT);

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java Thu Jul  2 16:57:17 2009
@@ -26,6 +26,7 @@
 import org.apache.openjpa.kernel.exps.AggregateListener;
 import org.apache.openjpa.kernel.exps.Constant;
 import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
@@ -335,5 +336,13 @@
          * {@link Constant}s, in cases where this query is for a bulk update.
 	 	 */
 		public Map getUpdates (StoreQuery q);
+		
+        /**
+         * Return the parsed query expressions for our candidate types.
+         * The expressions are available only after query has been parsed.
+         * 
+         * @since 2.0.0
+         */
+		public QueryExpressions[] getQueryExpressions();
 	}
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/QueryExpressions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/QueryExpressions.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/QueryExpressions.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/QueryExpressions.java Thu Jul  2 16:57:17 2009
@@ -69,7 +69,8 @@
     public String[] fetchInnerPaths = StoreQuery.EMPTY_STRINGS;
     public Value[] range = EMPTY_VALUES;
     private Boolean _aggregate = null;
-
+    public Object state;
+    
     /**
      * Whether this is an aggregate results.
      */

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Address.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Address.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Address.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Address.java Thu Jul  2 16:57:17 2009
@@ -24,7 +24,7 @@
 import javax.persistence.Table;
 
 @Entity
-@Table(name="ADDR_SQLCACHE")
+@Table(name="ADDR_PQC")
 public class Address {
 	@Id
 	@GeneratedValue

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Book.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Book.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Book.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Book.java Thu Jul  2 16:57:17 2009
@@ -39,6 +39,7 @@
     }
     
     public Book(String title) {
+        super();
         setTitle(title);
     }
     

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/CD.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/CD.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/CD.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/CD.java Thu Jul  2 16:57:17 2009
@@ -36,6 +36,7 @@
     }
     
     public CD(String label) {
+        super();
         setLabel(label);
     }
     public String getLabel() {

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Company.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Company.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Company.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Company.java Thu Jul  2 16:57:17 2009
@@ -24,6 +24,8 @@
 import javax.persistence.*;
 
 @Entity
+@Table(name="COMPANY_PQC")
+
 @NamedQueries({
 	@NamedQuery(name="Company.PreparedQueryWithNoParameter", 
 	    query="select x from Company x"),

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Department.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Department.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Department.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Department.java Thu Jul  2 16:57:17 2009
@@ -24,6 +24,8 @@
 import javax.persistence.*;
 
 @Entity
+@Table(name="DEPT_PQC")
+
 public class Department {
 	@Id
 	@GeneratedValue

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Employee.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Employee.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Employee.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Employee.java Thu Jul  2 16:57:17 2009
@@ -21,6 +21,8 @@
 import javax.persistence.*;
 
 @Entity
+@Table(name="EMPLOYEE_PQC")
+
 public class Employee {
 	@Id
 	@GeneratedValue
@@ -33,8 +35,18 @@
 	
 	@OneToOne
 	private Address address;
+	
+	private boolean isManager;
+
+	public boolean isManager() {
+        return isManager;
+    }
+
+    public void setManager(boolean isManager) {
+        this.isManager = isManager;
+    }
 
-	public String getName() {
+    public String getName() {
 		return name;
 	}
 

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Merchandise.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Merchandise.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Merchandise.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Merchandise.java Thu Jul  2 16:57:17 2009
@@ -18,12 +18,16 @@
  */
 package org.apache.openjpa.persistence.jdbc.sqlcache;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
+import javax.persistence.Table;
 
 @Entity
+@Table(name="MERCHANDISE_PQC")
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
 public class Merchandise {
     @Id

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Person.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Person.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Person.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Person.java Thu Jul  2 16:57:17 2009
@@ -18,9 +18,10 @@
  */
 package org.apache.openjpa.persistence.jdbc.sqlcache;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 import javax.persistence.DiscriminatorValue;
 import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
@@ -33,7 +34,7 @@
 
 
 @Entity
-@Table(name="PERSON_SQLCACHE")
+@Table(name="PERSON_PQC")
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
 @DiscriminatorValue("PERSON")
 @NamedQueries({
@@ -66,7 +67,6 @@
 })
 public class Person {
     @Id
-    @GeneratedValue
     private long id;
     
     private String firstName;
@@ -77,12 +77,15 @@
     @OneToOne
     private Address address;
     
+    private static AtomicLong idCounter = new AtomicLong(System.currentTimeMillis());
+    
     public Person() {
         this("?", "?", (short)0, 0);
     }
     
     public Person(String firstName, String lastName, short age, int yob) {
         super();
+        this.id = idCounter.getAndAdd(1);
         this.firstName = firstName;
         this.lastName = lastName;
         this.age = age;
@@ -131,4 +134,8 @@
     public long getId() {
         return id;
     }
+    
+    public void setId(long id) {
+        this.id = id;
+    }
 }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestFinderCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestFinderCache.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestFinderCache.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestFinderCache.java Thu Jul  2 16:57:17 2009
@@ -26,9 +26,7 @@
 
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.kernel.FinderCache;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
 import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 
 /**
  * Basic test to check FinderQuery caches.
@@ -38,11 +36,9 @@
  */
 public class TestFinderCache extends SQLListenerTestCase {
     public static final long[] BOOK_IDS = {1000, 2000, 3000};
-    public static final String[] BOOK_NAMES =
-            {"Argumentative Indian", "Tin Drum", "Blink"};
+    public static final String[] BOOK_NAMES = {"Argumentative Indian", "Tin Drum", "Blink"};
     public static final long[] CD_IDS = {1001, 2001, 3001};
-    public static final String[] CD_LABELS =
-            {"Beatles", "Sinatra", "Don't Rock My Boat"};
+    public static final String[] CD_LABELS =  {"Beatles", "Sinatra", "Don't Rock My Boat"};
     
     void createTestData() {
         EntityManager em = emf.createEntityManager();

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCache.java?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCache.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCache.java Thu Jul  2 16:57:17 2009
@@ -23,66 +23,104 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Properties;
 
 import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import junit.framework.TestCase;
 
-import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.kernel.PreparedQuery;
+import org.apache.openjpa.kernel.PreparedQueryCache;
 import org.apache.openjpa.kernel.QueryHints;
 import org.apache.openjpa.kernel.QueryLanguages;
-import org.apache.openjpa.kernel.PreparedQueryCache;
 import org.apache.openjpa.kernel.QueryStatistics;
 import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
+import org.apache.openjpa.lib.jdbc.JDBCEvent;
+import org.apache.openjpa.lib.jdbc.JDBCListener;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.OpenJPAPersistence;
 import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 
 /**
- * Performance oriented test to see comparative difference in response time with
- * or with SQL caching.
+ * Tests correctness and performance of queries with and without Prepared Query Cacheing.
+ *  
+ * This test uses a single EntityManagerFactory initialized with fixed set of entity classes 
+ * and appropriate configuration parameters for Prepared Query Cache. 
+ * 
+ * The entity classes are specified in persistence unit <code>"PreparedQuery"</code> in a 
+ * <code>META-INF/persistence.xml</code> that must be available to the classpath.
+ * 
+ * Configures the EntityManagerFactory with properties that are relevant to testing PreparedQuery caches.
+ * Switches off runtime enhancement to avoid unintended consequences.
+ * Provides facilities to run a JPQL query with and without cache and compute the performance delta. 
+ * 
+ * Uses a hard-coded data set initialized once for the entire suite. 
  * 
  * @author Pinaki Poddar
  * 
  */
-public class TestPreparedQueryCache extends SQLListenerTestCase {
-	// Fail if performance degrades with cache compared to without cache
-    public static final boolean FAIL_ON_PERF_DEGRADE = 
-        Boolean.getBoolean("FailOnPerformanceRegression");
-	
-	// # observations to compute timing statistics
-	public static final int SAMPLE_SIZE = 100;
-	
-	public static final boolean USE_CACHE                  = true;
-	public static final boolean IS_NAMED_QUERY             = true;
-	
-    public static final String[] COMPANY_NAMES = {"IBM", "BEA", "acme.org" };
-    public static final int[] START_YEARS = {1900, 2000, 2010 };
-	public static final String[] DEPARTMENT_NAMES = { "Marketing", "Sales",
-			"Engineering" };
-    public static final String[] EMPLOYEE_NAMES = { "Tom", "Dick", "Harray" };
-	public static final String[] CITY_NAMES = {"Tulsa", "Durban", "Harlem"};
-	
-    public static final String EXCLUDED_QUERY_1 =
-        "select count(p) from Company p";
-    public static final String EXCLUDED_QUERY_2 =
-        "select count(p) from Department p";
+public class TestPreparedQueryCache extends TestCase {
+    
+    private static String RESOURCE = "META-INF/persistence.xml"; 
+    private static String UNIT_NAME = "PreparedQuery";
+    
+    protected static final int SAMPLE_SIZE = 100;  // no. of observations for performance statistics 
+    public static final boolean USE_CACHE  = true; // mnemonic for using cache
+    private static Object[] NO_PARAMS      = null; // mnemonic for no query parameters
+    public static final boolean IS_NAMED_QUERY  = true; // mnemonic for named query
+    
+    private static boolean FAIL_IF_PERF_DEGRADE = false; 
+
+    
+    private static Company IBM;
+    public static final String[] COMPANY_NAMES    = {"IBM", "BEA", "acme.org" };
+    public static final int[]    START_YEARS      = {1900, 2000, 2010 };
+	public static final String[] DEPARTMENT_NAMES = {"Marketing", "Sales", "Engineering" };
+    public static final String[] EMPLOYEE_NAMES   = {"Tom", "Dick", "Harray" };
+	public static final String[] CITY_NAMES       = {"Tulsa", "Durban", "Harlem"};
+	
+    public static final String EXCLUDED_QUERY_1 = "select count(p) from Company p";
+    public static final String EXCLUDED_QUERY_2 = "select count(p) from Department p";
 	public static final String INCLUDED_QUERY   = "select p from Address p";
-	private Company IBM;
 	
-	public void setUp() throws Exception {
-		super.setUp(CLEAR_TABLES, Company.class, Department.class, 
-		    Employee.class, Address.class, 
-				"openjpa.jdbc.QuerySQLCache", 
-                "true(excludes='select count(p) from Company p;"
-                + "select count(p) from Department p')");
-		createTestData();
+    public static final long[] BOOK_IDS     = {1000, 2000, 3000};
+    public static final String[] BOOK_NAMES = {"Argumentative Indian", "Tin Drum", "Blink"};
+    public static final long[] CD_IDS       = {1001, 2001, 3001};
+    public static final String[] CD_LABELS  =  {"Beatles", "Sinatra", "Don't Rock My Boat"};
+    
+    protected static OpenJPAEntityManagerFactorySPI emf;
+    protected static SQLAuditor auditor;
+    private OpenJPAEntityManagerSPI em;
+	
+	/**
+	 * Sets up the test suite with a statically initialized EntityManagerFactory.
+	 * Creates data once for all other tests to use.
+	 */
+	public void setUp()  {
+        if (emf == null) {
+            Properties config = new Properties();
+            config.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true,SchemaAction='drop,add')");
+            config.put("openjpa.jdbc.JDBCListeners", new JDBCListener[] { auditor = new SQLAuditor()});
+            config.put("openjpa.jdbc.QuerySQLCache", "true");
+            config.put("openjpa.RuntimeUnenhancedClasses", "unsupported");
+            config.put("openjpa.DynamicEnhancementAgent", "false");
+            emf = (OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.createEntityManagerFactory(
+                    UNIT_NAME, RESOURCE, config);
+            em = emf.createEntityManager();
+            createTestData();
+        } else {
+    		em = emf.createEntityManager();
+            getPreparedQueryCache().clear();
+        }
 	}
 	
+	/**
+	 * Create data for the entire test suite to use.
+	 */
 	void createTestData() {
-	    EntityManager em = emf.createEntityManager();
 	    em.getTransaction().begin();
 	    for (int i = 0; i < COMPANY_NAMES.length; i++) {
 	        Company company = new Company();
@@ -108,42 +146,68 @@
 	            }
 	        }
 	    }
+        Person p1 = new Person("John", "Doe", (short)45, 1964);
+        Person p2 = new Person("John", "Doe", (short)42, 1967);
+        Person p3 = new Person("Harry", "Doe", (short)12, 1995);
+        Person p4 = new Person("Barry", "Doe", (short)22, 1985);
+        em.persist(p1);
+        em.persist(p2);
+        em.persist(p3);
+        em.persist(p4);
+        
+        Author a1 = new Author("Author1", "", (short)40, 1960);
+        Author a2 = new Author("Author2", "", (short)41, 1961);
+        Author a3 = new Author("Author3", "", (short)42, 1962);
+        Singer s1 = new Singer("Singer1", "", (short)21, 1991);
+        Singer s2 = new Singer("Singer2", "", (short)22, 1992);
+        
+        long id = 100;
+        Book   b1 = new Book("Book1");
+        Book   b2 = new Book("Book2");
+        CD     c1 = new CD("CD1");
+        CD     c2 = new CD("CD2");
+        
+        b1.setId(id++);
+        b2.setId(id++);
+        c1.setId(id++);
+        c2.setId(id++);
+        b1.addAuthor(a1);
+        b1.addAuthor(a2);
+        b2.addAuthor(a2);
+        b2.addAuthor(a3);
+        c1.setSinger(s1);
+        c2.setSinger(s2);
+        
+        em.persist(a1); em.persist(a2);   em.persist(a3);
+        em.persist(s1); em.persist(s2);
+        em.persist(b1); em.persist(b2);
+        em.persist(c1); em.persist(c2);
+
 	    em.getTransaction().commit();
 	}
 
 	public void tearDown() throws Exception {
+	    if (em.isOpen())
+	        em.close();
 		super.tearDown();
 	}
 	
-	PreparedQueryCache getCache() {
-		return emf.getConfiguration().getQuerySQLCacheInstance();
-	}
 
 	public void testPreparedQueryCacheIsActiveByDefault() {
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		assertTrue(conf.getQuerySQLCache().startsWith("true"));
-		assertNotNull(getCache());
-	}
-	
-	public void testPreparedQueryCacheCanBeDeactivatedDynamically() {
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		assertNotNull(getCache());
-		conf.setQuerySQLCache("false");
-		assertNull(getCache());
+		assertNotNull(getPreparedQueryCache());
 	}
 	
 	public void testPreparedQueryCacheIsPerUnitSingleton() {
-		PreparedQueryCache c1 = getCache();
-		PreparedQueryCache c2 = getCache();
+		PreparedQueryCache c1 = getPreparedQueryCache();
+		PreparedQueryCache c2 = getPreparedQueryCache();
 		assertSame(c1, c2);
 	}
 	
 	public void testPreparedQueryIdentifierIsOriginalJPQLQuery() {
         String jpql = "select p from Company p";
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAQuery q1 = em.createQuery(jpql);
+        OpenJPAQuery<?> q1 = em.createQuery(jpql);
         q1.getResultList();
-        PreparedQuery pq = getCache().get(jpql);
+        PreparedQuery pq = getPreparedQueryCache().get(jpql);
         assertNotNull(pq);
         assertEquals(jpql, pq.getIdentifier());
         assertEquals(jpql, pq.getOriginalQuery());
@@ -151,24 +215,22 @@
 	
 	public void testOriginalJPQLQueryStringIsSetOnPreparedQuery() {
         String jpql = "select p from Company p";
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAQuery q1 = em.createQuery(jpql);
+        OpenJPAQuery<?> q1 = em.createQuery(jpql);
         q1.getResultList();
-        PreparedQuery pq = getCache().get(jpql);
+        PreparedQuery pq = getPreparedQueryCache().get(jpql);
         assertNotNull(pq);
-        OpenJPAQuery q2 = em.createQuery(jpql);
+        OpenJPAQuery<?> q2 = em.createQuery(jpql);
         assertEquals(jpql,q2.getQueryString());
 	}
 
 	public void testOrderByElementsAbsentInProjection() {
 	    String jpql = "select c.name from Company c ORDER BY c.startYear";
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAQuery q1 = em.createQuery(jpql);
+        OpenJPAQuery<?> q1 = em.createQuery(jpql);
         List l1 = q1.getResultList();
         
-        PreparedQuery pq = getCache().get(jpql);
+        PreparedQuery pq = getPreparedQueryCache().get(jpql);
         assertNotNull(pq);
-        OpenJPAQuery q2 = em.createQuery(jpql);
+        OpenJPAQuery<?> q2 = em.createQuery(jpql);
         List l2 = q2.getResultList();
         
         assertEquals(l1.size(), l2.size());
@@ -176,32 +238,31 @@
 	}
 	
 	public void testExclusionPattern() {
-		OpenJPAEntityManager em = emf.createEntityManager();
-		OpenJPAQuery q1 = em.createQuery(EXCLUDED_QUERY_1);
+		OpenJPAQuery<?> q1 = em.createQuery(EXCLUDED_QUERY_1);
 		q1.getResultList();
 		assertNotCached(EXCLUDED_QUERY_1);
 		
-		OpenJPAQuery q2 = em.createQuery(EXCLUDED_QUERY_2);
+		OpenJPAQuery<?> q2 = em.createQuery(EXCLUDED_QUERY_2);
 		q2.getResultList();
 		assertNotCached(EXCLUDED_QUERY_2);
 		
-		OpenJPAQuery q3 = em.createQuery(INCLUDED_QUERY);
+		OpenJPAQuery<?> q3 = em.createQuery(INCLUDED_QUERY);
 		q3.getResultList();
 		assertCached(INCLUDED_QUERY);
 	}
 	
-	void assertLanguage(OpenJPAQuery q, String lang) {
+	void assertLanguage(OpenJPAQuery<?> q, String lang) {
 		assertEquals(lang, q.getLanguage());
 	}
 	
 	void assertCached(String id) {
-		PreparedQuery cached = getCache().get(id);
-		assertNotNull(getCache() + ": " + getCache().getMapView() + 
+		PreparedQuery cached = getPreparedQueryCache().get(id);
+		assertNotNull(getPreparedQueryCache() + ": " + getPreparedQueryCache().getMapView() + 
 				" does not contain " + id, cached);
 	}
 	
 	void assertNotCached(String id) {
-	    PreparedQueryCache cache = getCache();
+	    PreparedQueryCache cache = getPreparedQueryCache();
 		if (cache != null) {
 			assertNull(cache.get(id));
 		}
@@ -209,8 +270,7 @@
 	
 	public void testPreparedQueryIsCachedOnExecution() {
 		String jpql = "select p from Company p";
-		OpenJPAEntityManager em = emf.createEntityManager();
-		OpenJPAQuery q1 = em.createQuery(jpql);
+		OpenJPAQuery<?> q1 = em.createQuery(jpql);
 		assertNotCached(jpql);
 		assertLanguage(q1, JPQLParser.LANG_JPQL);
 		
@@ -218,15 +278,14 @@
 		assertCached(jpql);
 		assertLanguage(q1, JPQLParser.LANG_JPQL);
 		
-		PreparedQuery cached = getCache().get(jpql);
+		PreparedQuery cached = getPreparedQueryCache().get(jpql);
 		assertEquals(jpql, cached.getIdentifier());
-		assertNotEquals(jpql, cached.getTargetQuery());
+		assertFalse(jpql.equalsIgnoreCase(cached.getTargetQuery()));
 	}
 
 	public void testPreparedQueryIsCachedAcrossExecution() {
 		String jpql = "select p from Company p";
-		OpenJPAEntityManager em = emf.createEntityManager();
-		OpenJPAQuery q1 = em.createQuery(jpql);
+		OpenJPAQuery<?> q1 = em.createQuery(jpql);
 		assertNotCached(jpql);
 		assertLanguage(q1, JPQLParser.LANG_JPQL);
 		
@@ -237,15 +296,14 @@
 		
 		// Create a new query with the same JPQL
 		// This is not only cached, its language is different too
-		OpenJPAQuery q2 = em.createQuery(jpql);
+		OpenJPAQuery<?> q2 = em.createQuery(jpql);
 		assertCached(jpql);
 		assertLanguage(q2, QueryLanguages.LANG_PREPARED_SQL);
 	}
 	
 	public void testInvalidatePreparedQueryWithHint() {
 		String jpql = "select p from Company p";
-		OpenJPAEntityManager em = emf.createEntityManager();
-		OpenJPAQuery q1 = em.createQuery(jpql);
+		OpenJPAQuery<?> q1 = em.createQuery(jpql);
 		assertNotCached(jpql);
 		
 		q1.getResultList();
@@ -254,7 +312,7 @@
 		
 		// Create a new query with the same JPQL
 		// This is cached on creation, its language is Prepared SQL
-		OpenJPAQuery q2 = em.createQuery(jpql);
+		OpenJPAQuery<?> q2 = em.createQuery(jpql);
 		assertCached(jpql);
 		assertLanguage(q2, QueryLanguages.LANG_PREPARED_SQL);
 		q2.getResultList();
@@ -268,15 +326,14 @@
 		
 		// Create a new query with the same JPQL
 		// This is not cached on creation, its language is JPQL
-		OpenJPAQuery q3 = em.createQuery(jpql);
+		OpenJPAQuery<?> q3 = em.createQuery(jpql);
 		assertNotCached(jpql);
 		assertLanguage(q3, JPQLParser.LANG_JPQL);
 	}
 	
 	public void testIgnorePreparedQueryWithHint() {
 		String jpql = "select p from Company p";
-		OpenJPAEntityManager em = emf.createEntityManager();
-		OpenJPAQuery q1 = em.createQuery(jpql);
+		OpenJPAQuery<?> q1 = em.createQuery(jpql);
 		assertNotCached(jpql);
 		
 		q1.getResultList();
@@ -285,7 +342,7 @@
 		
 		// Create a new query with the same JPQL
 		// This is cached on creation, its language is PREPARED SQL
-		OpenJPAQuery q2 = em.createQuery(jpql);
+		OpenJPAQuery<?> q2 = em.createQuery(jpql);
 		assertCached(jpql);
 		assertLanguage(q2, QueryLanguages.LANG_PREPARED_SQL);
 		q2.getResultList();
@@ -300,28 +357,28 @@
 		
 		// Create a new query with the same JPQL
 		// This is cached on creation, its language is PREPARED SQL
-		OpenJPAQuery q3 = em.createQuery(jpql);
+		OpenJPAQuery<?> q3 = em.createQuery(jpql);
 		assertCached(jpql);
 		assertLanguage(q3, QueryLanguages.LANG_PREPARED_SQL);
 	}
 
 	public void testQueryStatistics() {
-		String jpql1 = "select c from Company c";
+        QueryStatistics<String> stats = getPreparedQueryCache().getStatistics();
+        stats.reset();
+
+        String jpql1 = "select c from Company c";
         String jpql2 = "select c from Company c where c.name = 'PObject'";
-		OpenJPAEntityManager em = emf.createEntityManager();
 		int N1 = 5;
 		int N2 = 8;
 		for (int i = 0; i < N1; i++) {
-	        OpenJPAQuery q1 = em.createQuery(jpql1);
+	        OpenJPAQuery<?> q1 = em.createQuery(jpql1);
 			q1.getResultList();
 		}
 		for (int i = 0; i < N2; i++) {
-	        OpenJPAQuery q2 = em.createQuery(jpql2);
+	        OpenJPAQuery<?> q2 = em.createQuery(jpql2);
 			q2.getResultList();
 		}
 		
-		QueryStatistics stats = getCache().getStatistics();
-
 		assertEquals(N1,      stats.getExecutionCount(jpql1));
 		assertEquals(N2,      stats.getExecutionCount(jpql2));
 		assertEquals(N1+N2,   stats.getExecutionCount());
@@ -332,21 +389,22 @@
 	}
 
 	public void testResetQueryStatistics() {
+        QueryStatistics<String> stats = getPreparedQueryCache().getStatistics();
+        stats.reset();
+        
 		String jpql1 = "select c from Company c";
         String jpql2 = "select c from Company c where c.name = 'PObject'";
-		OpenJPAEntityManager em = emf.createEntityManager();
 		int N10 = 4;
 		int N20 = 7;
 		for (int i = 0; i < N10; i++) {
-	        OpenJPAQuery q1 = em.createQuery(jpql1);
+	        OpenJPAQuery<?> q1 = em.createQuery(jpql1);
 			q1.getResultList();
 		}
 		for (int i = 0; i < N20; i++) {
-	        OpenJPAQuery q2 = em.createQuery(jpql2);
+	        OpenJPAQuery<?> q2 = em.createQuery(jpql2);
 			q2.getResultList();
 		}
 		
-		QueryStatistics stats = getCache().getStatistics();
 		assertEquals(N10,       stats.getExecutionCount(jpql1));
 		assertEquals(N20,       stats.getExecutionCount(jpql2));
 		assertEquals(N10+N20,   stats.getExecutionCount());
@@ -359,11 +417,11 @@
 		int N11 = 7;
 		int N21 = 4;
 		for (int i = 0; i < N11; i++) {
-            OpenJPAQuery q1 = em.createQuery(jpql1);
+            OpenJPAQuery<?> q1 = em.createQuery(jpql1);
 			q1.getResultList();
 		}
 		for (int i = 0; i < N21; i++) {
-            OpenJPAQuery q2 = em.createQuery(jpql2);
+            OpenJPAQuery<?> q2 = em.createQuery(jpql2);
 			q2.getResultList();
 		}
 
@@ -374,9 +432,9 @@
 		assertEquals(N21,     stats.getHitCount(jpql2));
 		assertEquals(N11+N21, stats.getHitCount());
 		
-		assertEquals(N10+N11,     stats.getTotalExecutionCount(jpql1));
-		assertEquals(N20+N21,     stats.getTotalExecutionCount(jpql2));
-		assertEquals(N10+N11+N20+N21, stats.getTotalExecutionCount());
+//		assertEquals(N10+N11,     stats.getTotalExecutionCount(jpql1));
+//		assertEquals(N20+N21,     stats.getTotalExecutionCount(jpql2));
+//		assertEquals(N10+N11+N20+N21, stats.getTotalExecutionCount());
 		assertEquals(N10+N11-1,     stats.getTotalHitCount(jpql1));
 		assertEquals(N20+N21-1,     stats.getTotalHitCount(jpql2));
 		assertEquals(N10+N11+N20+N21-2, stats.getTotalHitCount());
@@ -385,21 +443,18 @@
 
 	public void testQueryWithNoParameter() {
 		String jpql = "select p from Company p";
-		Object[] params = null;
-		compare(!IS_NAMED_QUERY, jpql, COMPANY_NAMES.length, params);
+		compare(jpql, !IS_NAMED_QUERY);
 	}
 
 	public void testQueryWithLiteral() {
-        String jpql = "select p from Company p where p.name = "
-                + literal(COMPANY_NAMES[0]);
-		Object[] params = null;
-		compare(!IS_NAMED_QUERY, jpql, 1, params);
+        String jpql = "select p from Company p where p.name = " + literal(COMPANY_NAMES[0]);
+		compare(jpql, !IS_NAMED_QUERY);
 	}
 
 	public void testQueryWithParameter() {
 		String jpql = "select p from Company p where p.name = :param";
 		Object[] params = {"param", COMPANY_NAMES[0]};
-		compare(!IS_NAMED_QUERY, jpql, 1, params);
+		compare(jpql, !IS_NAMED_QUERY,  params);
 	}
 
 	public void testQueryWithJoinsAndParameters() {
@@ -411,40 +466,37 @@
 		Object[] params = { "emp", EMPLOYEE_NAMES[0], 
                             "dept", DEPARTMENT_NAMES[0],
 							"city", CITY_NAMES[0]};
-		compare(!IS_NAMED_QUERY, jpql, 1, params);
+		compare(jpql, !IS_NAMED_QUERY,  params);
 	}
 
 	public void testNamedQueryWithNoParameter() {
 		String namedQuery = "Company.PreparedQueryWithNoParameter";
-		Object[] params = null;
-        compare(IS_NAMED_QUERY, namedQuery, COMPANY_NAMES.length, params);
+        compare(namedQuery, IS_NAMED_QUERY);
 	}
 
 	public void testNamedQueryWithLiteral() {
 		String namedQuery = "Company.PreparedQueryWithLiteral";
-		Object[] params = null;
-		compare(IS_NAMED_QUERY, namedQuery, 1, params);
+		compare(namedQuery, IS_NAMED_QUERY);
 	}
 
 	public void testNamedQueryWithPositionalParameter() {
         String namedQuery = "Company.PreparedQueryWithPositionalParameter";
 		Object[] params = {1, COMPANY_NAMES[0], 2, START_YEARS[0]};
-		compare(IS_NAMED_QUERY, namedQuery, 1, params);
+		compare(namedQuery, IS_NAMED_QUERY,  params);
 	}
 	
 	public void testNamedQueryWithNamedParameter() {
 		String namedQuery = "Company.PreparedQueryWithNamedParameter";
         Object[] params = {"name", COMPANY_NAMES[0], "startYear",
                 START_YEARS[0]};
-		compare(IS_NAMED_QUERY, namedQuery, 1, params);
+		compare(namedQuery, IS_NAMED_QUERY,  params);
 	}
 	
 	public void testPersistenceCapableParameter() {
         String jpql = "select e from Employee e " +
                 "where e.department.company=:company";
 	    Object[] params = {"company", IBM};
-	    compare(!IS_NAMED_QUERY, jpql,
-	            EMPLOYEE_NAMES.length * DEPARTMENT_NAMES.length, params);
+	    compare(jpql, !IS_NAMED_QUERY,  params);
 	}
 	
 	/**
@@ -454,8 +506,7 @@
         String jpql = "select e.name from Employee e " +
                 "where e.address.city=:city";
         Object[] params = {"city", CITY_NAMES[0]};
-        compare(!IS_NAMED_QUERY, jpql,
-                COMPANY_NAMES.length * DEPARTMENT_NAMES.length, params);
+        compare(jpql, !IS_NAMED_QUERY, params);
 	}
 	
 	public void testCollectionValuedParameters() {
@@ -467,135 +518,375 @@
                 Arrays.asList(new String[]{EMPLOYEE_NAMES[2]})};
         Object[] params3 = {"names", Arrays.asList(EMPLOYEE_NAMES)};
         
-        boolean checkHits = false;
-        
         int expectedCount = 2 * COMPANY_NAMES.length * DEPARTMENT_NAMES.length;
-        run(jpql, params1, USE_CACHE, 2, !IS_NAMED_QUERY, expectedCount,
-                checkHits);
-        assertCached(jpql);
+        run(jpql, !IS_NAMED_QUERY, params1, expectedCount, USE_CACHE, 1);
         
         expectedCount = 1 * COMPANY_NAMES.length * DEPARTMENT_NAMES.length;
-        run(jpql, params2, USE_CACHE, 2, !IS_NAMED_QUERY, expectedCount,
-                checkHits);
+        run(jpql, !IS_NAMED_QUERY, params2, expectedCount, USE_CACHE, 1);
         
-        expectedCount = EMPLOYEE_NAMES.length * COMPANY_NAMES.length *
-                DEPARTMENT_NAMES.length;
-        run(jpql, params3, USE_CACHE, 2, !IS_NAMED_QUERY, expectedCount,
-                checkHits);
+        expectedCount = EMPLOYEE_NAMES.length * COMPANY_NAMES.length * DEPARTMENT_NAMES.length;
+        run(jpql, !IS_NAMED_QUERY, params3, expectedCount, USE_CACHE, 1);
 	}
 	
-	/**
-	 * Compare the result of execution of the same query with and without
-	 * Prepared Query Cache.
-	 * 
-	 */
-    void compare(boolean isNamed, String jpql, int expectedCount,
-            Object... params) {
-		String realJPQL = isNamed ? getJPQL(jpql) : jpql;
-		// run the query once for warming up 
-		run(jpql, params, !USE_CACHE, 1, isNamed, expectedCount);
-		
-		// run N times without cache
-        long without = run(jpql, params, !USE_CACHE, SAMPLE_SIZE, isNamed,
-                expectedCount);
-		assertNotCached(realJPQL);
-		
-		// run N times with cache
-        long with = run(jpql, params, USE_CACHE, SAMPLE_SIZE, isNamed,
-                expectedCount);
-		assertCached(realJPQL);
-		
-        long delta = (without == 0) ? 0 : (without - with) * 100 / without;
-		
-		if (delta < 0) {
-			if (FAIL_ON_PERF_DEGRADE)
-                assertFalse("change in execution time = " + delta + "%", 
-						delta < 0);
-		}
-	}
-
-    long run(String jpql, Object[] params, boolean useCache, int N, 
-        boolean isNamedQuery, int expectedCount) {
-        return run(jpql, params, useCache, N, isNamedQuery, expectedCount,
-                true);
+    public void testQueryProjectionNotCandidateClass() {
+        String jpql = "select e.department from Employee e";
+        compare(jpql, !IS_NAMED_QUERY);
     }
-	/**
-     * Create and run a query N times with the given parameters. The time for
-	 * each query execution is measured in nanosecond precision and 
-	 * median time taken in N observation is returned.  
-	 * 
-	 * returns median time taken for single execution.
-	 */
-	long run(String jpql, Object[] params, boolean useCache, int N, 
-            boolean isNamedQuery, int expectedCount, boolean checkHits) {
-		List<Long> stats = new ArrayList<Long>();
-		sql.clear();
-		for (int i = 0; i < N; i++) {
-	        OpenJPAEntityManager em = emf.createEntityManager();
-	        ((OpenJPAEntityManagerSPI)em).setQuerySQLCache(useCache);
-            assertEquals(useCache,
-                    ((OpenJPAEntityManagerSPI)em).getQuerySQLCache());
-			long start = System.nanoTime();
-			OpenJPAQuery q = isNamedQuery 
-                ? em.createNamedQuery(jpql) : em.createQuery(jpql);
-            for (int j = 0; params != null && j < params.length - 1; j += 2) {
-				Object key = params[j];
-				Object val = params[j + 1];
-				if (key instanceof Integer)
-                    q.setParameter(((Number)key).intValue(), val); 
-				else if (key instanceof String)
-					q.setParameter(key.toString(), val); 
-				else
-                    fail("key " + key + " is neither Number nor String");
-			}
-			List list = q.getResultList();
-			walk(list);
-			int actual = list.size();
-			q.closeAll();
-			assertEquals(expectedCount, actual);
-			long end = System.nanoTime();
-			stats.add(end - start);
-	        em.close();
-		}
-        if (useCache && checkHits) {
-            String cacheKey = isNamedQuery ? getJPQL(jpql) : jpql;
-            long total = getCache().getStatistics().getExecutionCount(cacheKey);
-            long hits = getCache().getStatistics().getHitCount(cacheKey);
-            assertEquals(N, total);
-            assertEquals(N-1, hits);
-        }
-        assertEquals(N, sql.size());
-        Collections.sort(stats);
-		return stats.get(N/2);
-	}	
-	
-	/**
-	 * Get the SQL corresponding to the given query key.
-	 * @param jpql
-	 * @return
-	 */
-	String getSQL(String queryKey) {
-        PreparedQueryCache cache =
-            emf.getConfiguration().getQuerySQLCacheInstance();
-		if (cache == null)
-			return "null";
-		PreparedQuery query = cache.get(queryKey);
-		return (query != null) ? query.getTargetQuery() : "null";
-	}
-	
-	String getJPQL(String namedQuery) {
-		return emf.getConfiguration().getMetaDataRepositoryInstance()
-                  .getQueryMetaData(null, namedQuery, null, true)
-				  .getQueryString();
-	}
+    
+    public void testQueryMultipleProjectionClass() {
+        String jpql = "select d, e from Department d, in (d.employees) e";
+        compare(jpql, !IS_NAMED_QUERY);
+    }
+    
+    public void testQueryWithOrderByClause() {
+        String jpql = "select e.name from Employee e order by e.id";
+        compare(jpql, !IS_NAMED_QUERY);
+    }
+    
+    public void testQueryCount() {
+        String jpql = "select count(e),d from Department d join d.employees e group by d";
+        compare(jpql, !IS_NAMED_QUERY);
+    }
+    
+    public void testProjectRepeatsTerm() {
+        String jpql = "select e.name, e.name from Employee e";
+        compare(jpql, !IS_NAMED_QUERY);
+    }
+    
+    public void testProjectEmbedded() {
+        String jpql = "select e.address from Employee e";
+        compare(jpql, !IS_NAMED_QUERY);
+    }
+    
+    public void testNeedsTypeConversion() {
+        String jpql = "select e.name, e.isManager from Employee e";
+        compare(jpql, !IS_NAMED_QUERY);
+    }    
 	
 	String literal(String s) {
 	    return "'"+s+"'";
 	}
 	
-	void walk(List list) {
-	    Iterator i = list.iterator();
-	    while (i.hasNext())
-	        i.next();
-	}
+    public void testPositional() {
+        String jpql = "select p from Person p where p.firstName=?1" +
+                      " and p.lastName='Doe' and p.age > ?2";
+        EntityManager em = emf.createEntityManager();
+        
+        OpenJPAQuery<?> q1 = OpenJPAPersistence.cast(em.createQuery(jpql));
+        assertEquals(JPQLParser.LANG_JPQL, q1.getLanguage());
+        
+        List<?> result1 = q1.setParameter(1, "John")
+                       .setParameter(2, (short)40)
+                       .getResultList();
+        
+        assertEquals(2, result1.size());
+        
+        OpenJPAQuery<?> q2 = OpenJPAPersistence.cast(em.createQuery(jpql));
+        assertEquals(QueryLanguages.LANG_PREPARED_SQL, q2.getLanguage());
+        List<?> result2 = q2.setParameter(1, "Harry")
+                  .setParameter(2, (short)10)
+                  .getResultList();
+        
+        assertEquals(1, result2.size());
+    }
+    
+    public void testNamed() {
+        String jpql = "select p from Person p where p.firstName=:first" +
+                      " and p.lastName='Doe' and p.age > :age";
+        EntityManager em = emf.createEntityManager();
+        
+        OpenJPAQuery<?> q1 = OpenJPAPersistence.cast(em.createQuery(jpql));
+        assertEquals(JPQLParser.LANG_JPQL, q1.getLanguage());
+        
+        List<?> result1 = q1.setParameter("first", "John")
+                       .setParameter("age", (short)40)
+                       .getResultList();
+        
+        assertEquals(2, result1.size());
+        
+        OpenJPAQuery<?> q2 = OpenJPAPersistence.cast(em.createQuery(jpql));
+        assertEquals(QueryLanguages.LANG_PREPARED_SQL, q2.getLanguage());
+        List<?> result2 = q2.setParameter("first", "Barry")
+                  .setParameter("age", (short)20)
+                  .getResultList();
+        
+        assertEquals(1, result2.size());
+    }
+    
+    public void testWrongParameterValueTypeThrowException() {
+        String jpql = "select p from Person p where p.firstName=:first" 
+                    + " and p.age > :age";
+        EntityManager em = emf.createEntityManager();
+
+        OpenJPAQuery<?> q1 = OpenJPAPersistence.cast(em.createQuery(jpql));
+        try {
+            List<?> result1 = q1.setParameter("first", (short)40)
+                             .setParameter("age", "John")
+                             .getResultList();
+            fail("Expected to fail with wrong parameter value");
+        } catch (IllegalArgumentException e) {
+            // good
+        }
+    }
+    
+    public void testNullParameterValueForPrimitiveTypeThrowsException() {
+        String jpql = "select p from Person p where p.firstName=:first" 
+                    + " and p.age > :age";
+        EntityManager em = emf.createEntityManager();
+
+        OpenJPAQuery<?> q1 = OpenJPAPersistence.cast(em.createQuery(jpql));
+        try {
+            List<?> result1 = q1.setParameter("first", "John")
+                             .setParameter("age", null)
+                             .getResultList();
+            fail("Expected to fail with null parameter value for primitives");
+        } catch (RuntimeException e) {
+            // good
+        }
+    }
+    public void testQueryWithLazyRelationIsCached() {
+        // Author is lazily related to Book
+        String jpql = "select p from Author p";
+        EntityManager em = emf.createEntityManager();
+        
+        Query q1 = em.createQuery(jpql);
+        assertEquals(OpenJPAPersistence.cast(q1).getLanguage(),
+                JPQLParser.LANG_JPQL);
+        List<Author> authors1 = q1.getResultList();
+        assertFalse(authors1.isEmpty());
+        Author author1 = authors1.iterator().next();
+        em.close(); // nothing will be loaded by chance
+        
+        assertNull(author1.getBooks());
+        
+        // do the same thing again, this time query should be cached
+        em = emf.createEntityManager();
+        Query q2 = em.createQuery(jpql);
+        assertEquals(OpenJPAPersistence.cast(q2).getLanguage(),
+                QueryLanguages.LANG_PREPARED_SQL);
+        List<Author> authors2 = q2.getResultList();
+        assertFalse(authors2.isEmpty());
+        Author author2 = authors2.iterator().next();
+        em.close();
+        
+        assertNull(author2.getBooks());
+    }
+    
+    public void testQueryWithEagerRelationIsNotCached() {
+        // Book is eagerly related to Author
+        String jpql = "select b from Book b";
+        EntityManager em = emf.createEntityManager();
+        
+        Query q1 = em.createQuery(jpql);
+        assertEquals(OpenJPAPersistence.cast(q1).getLanguage(),
+                JPQLParser.LANG_JPQL);
+        List<Book> books = q1.getResultList();
+        assertFalse(books.isEmpty());
+        Book book1 = books.iterator().next();
+        em.close(); // nothing will be loaded by chance
+        
+        assertNotNull(book1.getAuthors());
+        assertFalse(book1.getAuthors().isEmpty());
+        
+        // do the same thing again, this time query should not be cached
+        // because it requires multiple selects
+        em = emf.createEntityManager();
+        Query q2 = em.createQuery(jpql);
+        assertEquals(OpenJPAPersistence.cast(q2).getLanguage(),
+                JPQLParser.LANG_JPQL);
+        List<Book> books2 = q2.getResultList();
+        assertFalse(books2.isEmpty());
+        Book book2 = books2.iterator().next();
+        em.close();
+        
+        assertNotNull(book2.getAuthors());
+        assertFalse(book2.getAuthors().isEmpty());
+    }
+    PreparedQueryCache getPreparedQueryCache() {
+        return emf.getConfiguration().getQuerySQLCacheInstance();
+    }
+    
+    /**
+     * Compare the result of execution of the non-parameterized query with and without PreparedQuery cache.
+     * 
+     * @param jpql a String representing either a JPQL or the name of a NamedQuery
+     * @param isNamedQuery flags if the first input represents a JPQL string or a NamedQuery name
+     */
+    void compare(String jpql, boolean isNamed) {
+        compare(jpql, isNamed, -1, NO_PARAMS);
+    }
+
+    
+    /**
+     * Compare the result of execution of the non-parameterized query with and without PreparedQuery cache.
+     * 
+     * @param jpql a String representing either a JPQL or the name of a NamedQuery
+     * @param isNamedQuery flags if the first input represents a JPQL string or a NamedQuery name
+     * @param expectedCount expected number of results
+     */
+    void compare(String jpql, boolean isNamed, int expectedCount) {
+        compare(jpql, isNamed, expectedCount, NO_PARAMS);
+    }
+    
+    /**
+     * Compare the result of execution of the query with and without PreparedQuery cache.
+     * 
+     * 
+     * @param jpql a String representing either a JPQL or the name of a NamedQuery
+     * @param isNamedQuery flags if the first input represents a JPQL string or a NamedQuery name
+     * @param params a even sized array whose even-indexed elements are keys and odd-indexed elements are corresponding
+     * parameter value for the query. A null array denotes the query is not parameterized.
+     */
+    void compare(String jpql, boolean isNamed, Object... params) {
+        compare(jpql, isNamed, -1, params);
+    }
+    /**
+     * Compare the result of execution of the query with and without PreparedQuery cache.
+     * 
+     * 
+     * @param jpql a String representing either a JPQL or the name of a NamedQuery
+     * @param isNamedQuery flags if the first input represents a JPQL string or a NamedQuery name
+     * @param params a even sized array whose even-indexed elements are keys and odd-indexed elements are corresponding
+     * parameter value for the query. A null array denotes the query is not parameterized.
+     * @param expectedCount expected number of results. Supply a negative number to ignore.
+     */
+    void compare(String query, boolean isNamed, int expectedCount, Object... params) {
+        run(query, isNamed, params, expectedCount, !USE_CACHE, 1); // run the query once for warming up
+        
+        // run N times without cache
+        auditor.clear();
+        long without = run(query, isNamed, params, expectedCount, !USE_CACHE, SAMPLE_SIZE);
+        List<String> originalSQLs = auditor.getSQLs();
+        
+        // run N times with cache
+        auditor.clear();
+        long with = run(query, isNamed, params, expectedCount, USE_CACHE, SAMPLE_SIZE);
+        List<String> cachedSQLs = auditor.getSQLs();
+        
+        compareSQLs(originalSQLs, cachedSQLs);
+        long delta = (without == 0) ? 0 : (without - with) * 100 / without;
+        
+        String jpql = getJPQLString(query, isNamed);
+        System.err.println((delta < 0 ? "***WARN " : "") + Math.abs(delta) + "% " + 
+                (delta < 0 ? "degradtion" : "improvement") + " for ["+ jpql + "]");
+        assertTrue(Math.abs(delta) + "% degradtion for ["+ jpql + "]", !FAIL_IF_PERF_DEGRADE || delta > 0);
+    }
+    
+    void compareSQLs(List<String> a, List<String> b) {
+        assertEquals(a.size(), b.size());
+        for (int i = 0; i < a.size(); i++) {
+            assertEquals(a.get(i), b.get(i));
+        }
+    }
+
+    /**
+     * Create a query from the given string and execute it for given number of times.
+     * 
+     * @param jpql a String representing either a JPQL or the name of a NamedQuery
+     * @param isNamedQuery flags if the first input represents a JPQL string or a NamedQuery name
+     * @param params a even sized array whose even-indexed elements are keys and odd-indexed elements are corresponding
+     * parameter value for the query. A null array denotes the query is not parameterized.
+     * @param expectedCount expected number of results. Supply a negative number to ignore.
+     * @param useCache flags if the PreparedQuery cache is to be activated.
+     * @param N number of times the query is to be executed to calculate reasonable statistics.
+     * 
+     * @return median time to execute a query and iterate through its results 
+     */
+    long run(String jpql, boolean isNamedQuery, Object[] params, int expectedCount, boolean useCache, int N) {
+        List<Long> stats = new ArrayList<Long>();
+        String cacheKey = getJPQLString(jpql, isNamedQuery);
+        QueryStatistics<String> cacheStats = getPreparedQueryCache().getStatistics();
+        getPreparedQueryCache().clear();
+        assertEquals(0, cacheStats.getExecutionCount(cacheKey));
+        assertEquals(0, cacheStats.getHitCount(cacheKey));
+        
+        for (int i = 0; i < N; i++) {
+            OpenJPAEntityManagerSPI em = (OpenJPAEntityManagerSPI)emf.createEntityManager();
+            em.setQuerySQLCache(useCache);
+            assertEquals(useCache, em.getQuerySQLCache());
+            
+            // measure time 
+            long start = System.nanoTime();
+            OpenJPAQuery<?> q = isNamedQuery ? em.createNamedQuery(jpql) : em.createQuery(jpql);
+            parameterize(q, params);
+            List<?> list = q.getResultList();
+            if (expectedCount >= 0)
+                assertEquals(expectedCount, list.size());
+            else
+                assertFalse(list.isEmpty());
+            iterate(list);
+            long end = System.nanoTime();   
+            
+            assertEquals(useCache ? i+1 : 0, cacheStats.getExecutionCount(cacheKey));
+            assertEquals(useCache ? i : 0,   cacheStats.getHitCount(cacheKey));
+            
+            q.closeAll();
+            stats.add(end - start);
+            em.close();
+        }
+        assertEquals("Execution Count [" + cacheKey + "]", useCache ? N : 0, cacheStats.getTotalExecutionCount());
+        assertEquals("Hit Count [" + cacheKey + "]", useCache ? N-1 : 0, cacheStats.getTotalHitCount());
+        
+        Collections.sort(stats);
+        return stats.get(N/2);
+    }   
+    
+    
+    void parameterize(Query q, Object[] params) {
+        if (params == null)
+            return;
+        for (int j = 0; params != null && j < params.length - 1; j += 2) {
+            Object key = params[j];
+            Object val = params[j + 1];
+            if (key instanceof Integer)
+                q.setParameter(((Number)key).intValue(), val); 
+            else if (key instanceof String)
+                q.setParameter(key.toString(), val); 
+            else
+                fail("key " + key + " is neither Number nor String");
+        }
+    }
+    
+    void iterate(List<?> list) {
+        Iterator<?> i = list.iterator();
+        while (i.hasNext())
+            i.next();
+    }
+    
+    /**
+     * Gets the JPQL String of a NamedQuery of the given name.
+     */
+    String getJPQLString(String name, boolean isNamedQuery) {
+        if (!isNamedQuery)
+            return name;
+        return emf.getConfiguration()
+                  .getMetaDataRepositoryInstance()
+                  .getQueryMetaData(null, name, null, true)
+                  .getQueryString();
+    }
+
+
+    /**
+     * A JDBC Listener to audit target SQL executed per JPQL query.
+     *
+     */
+    public class SQLAuditor extends AbstractJDBCListener {
+        private List<String> sqls = new ArrayList<String>();
+    
+        @Override
+        public void beforeExecuteStatement(JDBCEvent event) {
+            if (event.getSQL() != null && sqls != null) {
+               sqls.add(event.getSQL());
+            }
+        }
+        
+        void clear() {
+            sqls.clear();
+        }
+        
+        List<String> getSQLs() {
+            return new ArrayList<String>(sqls);
+        }
+    }
+
 }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml?rev=790676&r1=790675&r2=790676&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml Thu Jul  2 16:57:17 2009
@@ -173,6 +173,27 @@
                 value="buildSchema"/> 
         </properties>
     </persistence-unit>
+    
+    <persistence-unit name="PreparedQuery" transaction-type="RESOURCE_LOCAL">
+        <description>PU for PreparedQueryCache testing</description>
+        
+        <class>org.apache.openjpa.persistence.jdbc.sqlcache.Address</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Author</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Book</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.CD</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Company</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Department</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Employee</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Merchandise</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Person</class>
+		<class>org.apache.openjpa.persistence.jdbc.sqlcache.Singer</class>
+		
+		<properties>
+		  <property name="openjpa.jdbc.QuerySQLCache"
+                    value="true(excludes='select count(p) from Company p;select count(p) from Department p')"/>
+        </properties>
+    </persistence-unit>
+
     <persistence-unit name="AbstractCallbackPU" transaction-type="RESOURCE_LOCAL">
         <description>PU for testing with an entity with no persistent attributes</description>
         <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
@@ -185,4 +206,5 @@
                 value="buildSchema"/> 
         </properties>
     </persistence-unit>    
+
 </persistence>



Mime
View raw message