You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/02/09 17:29:38 UTC

svn commit: r742601 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence/src/main/java/org/ap...

Author: ppoddar
Date: Mon Feb  9 16:29:37 2009
New Revision: 742601

URL: http://svn.apache.org/viewvc?rev=742601&view=rev
Log:
OPENJPA-703: Align data loading for Prepared Query Results to Select oriented result object provider

Added:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedResultObjectProvider.java
Modified:
    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/SelectResultObjectProvider.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQuery.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    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/PreparedQueryCacheImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java?rev=742601&r1=742600&r2=742601&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 Mon Feb  9 16:29:37 2009
@@ -76,7 +76,6 @@
         if (id == null 
             || query == null 
             || QueryLanguages.LANG_SQL.equals(query.getLanguage()) 
-            || !isSelect(query.getQueryString())
             || isHinted(hints, QueryHints.HINT_IGNORE_PREPARED_QUERY)
             || isHinted(hints, QueryHints.HINT_INVALIDATE_PREPARED_QUERY))
             return Boolean.FALSE;
@@ -343,12 +342,6 @@
         Object result = fetch.getHint(hint);
         return result != null && "true".equalsIgnoreCase(result.toString());
     }
-    
-    boolean isSelect(String s) {
-        return s != null
-            && s.length()>SELECT.length()
-            && s.trim().substring(0,SELECT.length()).equalsIgnoreCase(SELECT);
-    }
         
 	//-------------------------------------------------------
 	// 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=742601&r1=742600&r2=742601&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 Mon Feb  9 16:29:37 2009
@@ -29,8 +29,12 @@
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.meta.MappingRepository;
 import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.LogicalUnion;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
 import org.apache.openjpa.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.jdbc.sql.SelectImpl;
+import org.apache.openjpa.jdbc.sql.Union;
 import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.PreparedQuery;
 import org.apache.openjpa.kernel.Query;
@@ -39,6 +43,7 @@
 import org.apache.openjpa.lib.rop.ResultList;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.UserException;
 
 /**
@@ -53,6 +58,7 @@
 
     private final String _id;
     private String _sql;
+    private boolean _initialized;
     
     // Post-compilation state of an executable query, populated on construction
     private Class _candidate;
@@ -62,7 +68,8 @@
     // Position of the user defined parameters in the _params list
     private Map<Object, int[]>    _userParamPositions;
     private Map<Integer, Object> _template;
-    
+    private SelectImpl select;
+
     /**
      * Construct.
      * 
@@ -114,6 +121,10 @@
         _sql = sql;
     }
     
+    public boolean isInitialized() {
+        return _initialized;
+    }
+    
     /**
      * Pours the post-compilation state held by this receiver to the given
      * query.
@@ -122,7 +133,7 @@
         if (!_isProjection)
             q.setCandidateType(_candidate, _subclasses);
     }
-    
+
     /**
      * Initialize this receiver with post-execution result.
      * The input argument is processed only if it is a {@link ResultList} with
@@ -130,17 +141,25 @@
      * {@link ResultList#getUserObject() user object}. 
      */
     public boolean initialize(Object result) {
+        if (isInitialized())
+            return true;
         SelectExecutor selector = extractSelectExecutor(result);
-        if (selector == null)
+        if (selector == null || selector.hasMultipleSelects()
+          || ((selector instanceof Union) 
+          && (((Union)selector).getSelects().length != 1)))
             return false;
-        SQLBuffer buffer = selector == null ? null : selector.getSQL();
-        if (buffer != null && !selector.hasMultipleSelects()) {
-            setTargetQuery(buffer.getSQL());
-            setParameters(buffer.getParameters());
-            setUserParameterPositions(buffer.getUserParameters());
-            return true;
-        }
-        return false;
+        select = extractImplementation(selector);
+        if (select == null)
+            return false;
+        SQLBuffer buffer = selector.getSQL();
+        if (buffer == null)
+            return false;
+        setTargetQuery(buffer.getSQL());
+        setParameters(buffer.getParameters());
+        setUserParameterPositions(buffer.getUserParameters());
+        _initialized = true;
+        
+        return true;
     }
     
     /**
@@ -161,6 +180,19 @@
         return null;
     }
     
+    private SelectImpl extractImplementation(SelectExecutor selector) {
+        if (selector == null)
+            return null;
+        if (selector instanceof SelectImpl) 
+            return (SelectImpl)selector;
+        if (selector instanceof LogicalUnion.UnionSelect)
+            return ((LogicalUnion.UnionSelect)selector).getDelegate();
+        if (selector instanceof Union) 
+            return extractImplementation(((Union)selector).getSelects()[0]);
+        
+        return null;
+    }
+    
     /**
      * Merge the given user parameters with its own parameter. The given map
      * must be compatible with the user parameters extracted during 
@@ -170,6 +202,8 @@
      * 
      */
     public Map<Integer, Object> reparametrize(Map user, Broker broker) {
+        if (!isInitialized())
+            throw new InternalException("reparameterize() on uninitialized.");
         if (user == null || user.isEmpty()) {
             if (!_userParamPositions.isEmpty()) {
                 throw new UserException(_loc.get("uparam-null", 
@@ -287,6 +321,10 @@
         _template = Collections.unmodifiableMap(tmp);
     }
     
+    SelectImpl getSelect() {
+        return select;
+    }
+    
     public String toString() {
         return "PreparedQuery: [" + getOriginalQuery() + "] --> [" + 
                getTargetQuery() + "]";

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedResultObjectProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedResultObjectProvider.java?rev=742601&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedResultObjectProvider.java (added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedResultObjectProvider.java Mon Feb  9 16:29:37 2009
@@ -0,0 +1,53 @@
+/*
+ * 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.meta.ClassMapping;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SelectExecutor;
+
+/**
+ * A Select-oriented Result Object Provider whose Select has been executed
+ * outside its own scope.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+public class PreparedResultObjectProvider extends InstanceResultObjectProvider {
+    /**
+     * Constructor.
+     *
+     * @param sel the select to execute
+     * @param store the store to delegate loading to
+     * @param fetch the fetch configuration, or null for the default
+     * @param res the result of the given select
+     */
+    public PreparedResultObjectProvider(SelectExecutor sel,
+        ClassMapping mapping, JDBCStore store, JDBCFetchConfiguration fetch, 
+        Result res) {
+        super(sel, mapping, store, fetch);
+        _res = res;
+    }
+    
+    public void open() throws SQLException {
+        // do nothing
+    }
+}

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=742601&r1=742600&r2=742601&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 Mon Feb  9 16:29:37 2009
@@ -26,13 +26,16 @@
 
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.Result;
 import org.apache.openjpa.jdbc.sql.ResultSetResult;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
 import org.apache.openjpa.jdbc.sql.SQLExceptions;
+import org.apache.openjpa.jdbc.sql.SelectImpl;
 import org.apache.openjpa.kernel.StoreQuery;
 import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
 import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.InternalException;
 
 /**
  * A executor for Prepared SQL Query.
@@ -41,6 +44,7 @@
  *
  */
 public class PreparedSQLStoreQuery extends SQLStoreQuery {
+    private PreparedQueryImpl _cached;
     public PreparedSQLStoreQuery(JDBCStore store) {
         super(store);
     }
@@ -50,6 +54,19 @@
         return new PreparedSQLExecutor(this, meta);
     }
     
+    public boolean setQuery(Object query) {
+        if (query instanceof PreparedQueryImpl == false) {
+            throw new InternalException(query.getClass() + " not recognized");
+        }
+        _cached = (PreparedQueryImpl)query;
+        return true;
+    }
+    
+    PreparedQueryImpl getPreparedQuery() {
+        return _cached;
+    }
+
+    
     public static class PreparedSQLExecutor extends AbstractExecutor {
         private final ClassMetaData _meta;
         public PreparedSQLExecutor(PreparedSQLStoreQuery q, 
@@ -63,11 +80,12 @@
 
         public ResultObjectProvider executeQuery(StoreQuery q,
             Object[] params, Range range) {
-            JDBCStore store = ((SQLStoreQuery) q).getStore();
+            PreparedSQLStoreQuery psq = (PreparedSQLStoreQuery) q;
+            PreparedQueryImpl pq = psq.getPreparedQuery();
+            JDBCStore store = psq.getStore();
             DBDictionary dict = store.getDBDictionary();
 
-            SQLBuffer buf = new SQLBuffer(dict)
-                .append(q.getContext().getQueryString());
+            SQLBuffer buf = new SQLBuffer(dict).append(pq.getTargetQuery());
             Connection conn = store.getConnection();
             JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)
                 q.getContext().getFetchConfiguration();
@@ -84,14 +102,16 @@
                     dict.setUnknown(stmnt, ++index, params[i], null);
 
                 ResultSet rs = stmnt.executeQuery();
-                ResultSetResult res = new ResultSetResult(conn, stmnt, rs, 
-                    store);
+                
+                SelectImpl cachedSelect = pq.getSelect();
+                Result res = cachedSelect.getEagerResult(conn, stmnt, rs, 
+                    store, fetch, false, null);
                 if (q.getContext().getCandidateType() != null)
-                    rop = new GenericResultObjectProvider((ClassMapping) _meta,
-                        store, fetch, res);
+                    rop = new PreparedResultObjectProvider(cachedSelect, 
+                        (ClassMapping) _meta, store, fetch, res);
                 else
                     rop = new SQLProjectionResultObjectProvider(store, fetch,
-                        res, q.getContext().getResultType());
+                        (ResultSetResult)res, q.getContext().getResultType());
             } catch (SQLException se) {
                 if (stmnt != null)
                     try { stmnt.close(); } catch (SQLException se2) {}

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SelectResultObjectProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SelectResultObjectProvider.java?rev=742601&r1=742600&r2=742601&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SelectResultObjectProvider.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SelectResultObjectProvider.java Mon Feb  9 16:29:37 2009
@@ -39,7 +39,7 @@
     private final SelectExecutor _sel;
     private final JDBCStore _store;
     private final JDBCFetchConfiguration _fetch;
-    private Result _res = null;
+    protected Result _res = null;
     private int _size = -1;
     private Boolean _ra = null;
 

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java?rev=742601&r1=742600&r2=742601&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java Mon Feb  9 16:29:37 2009
@@ -315,7 +315,7 @@
     /**
      * A select that is part of a logical union.
      */
-    protected class UnionSelect
+    public class UnionSelect
         implements Select {
 
         protected final SelectImpl sel;

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=742601&r1=742600&r2=742601&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Mon Feb  9 16:29:37 2009
@@ -482,7 +482,7 @@
      * This method is to provide override for non-JDBC or JDBC-like 
      * implementation of executing eager selects.
      */
-    protected Result getEagerResult(Connection conn, 
+    public Result getEagerResult(Connection conn, 
         PreparedStatement stmnt, ResultSet rs, JDBCStore store, 
         JDBCFetchConfiguration fetch, boolean forUpdate, SQLBuffer sql) 
         throws SQLException {

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQuery.java?rev=742601&r1=742600&r2=742601&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQuery.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQuery.java Mon Feb  9 16:29:37 2009
@@ -65,6 +65,9 @@
      */
     public String getOriginalQuery();
     
+    /**
+     * Gets the language in which this query is expressed.
+     */
     public String getLanguage();
     
     /**
@@ -89,9 +92,16 @@
 	public boolean initialize(Object o);
 	
 	/**
+	 * Affirms if this receiver has been initialized.
+	 */
+	public boolean isInitialized();
+	
+	/**
 	 * Get the list of parameters in a map where an entry represents a parameter
 	 * key and value after replacing with the given user parameters. 
 	 * 
+	 * Must be invoked after initialize().  
+	 * 
 	 * @param user the map of parameter key and value set by the user on the
 	 * original query.
 	 */

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=742601&r1=742600&r2=742601&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Mon Feb  9 16:29:37 2009
@@ -880,9 +880,9 @@
                 ? getPreparedQuery(qid) : null;
             org.apache.openjpa.kernel.Query q = (pq == null)
                 ? _broker.newQuery(language, query)
-                : _broker.newQuery(pq.getLanguage(), pq.getTargetQuery());
+                : _broker.newQuery(pq.getLanguage(), pq);
             // have to validate JPQL according to spec
-            if (JPQLParser.LANG_JPQL.equals(language))
+            if (pq == null && JPQLParser.LANG_JPQL.equals(language))
                 q.compile(); 
             if (pq != null) {
                 pq.setInto(q);
@@ -915,14 +915,14 @@
                 ? getPreparedQuery(qid) : null;
             org.apache.openjpa.kernel.Query del = (pq == null)
                 ? _broker.newQuery(meta.getLanguage(), meta.getQueryString())
-                : _broker.newQuery(pq.getLanguage(), pq.getTargetQuery());
+                : _broker.newQuery(pq.getLanguage(), pq);
             
             if (pq != null) {
                 pq.setInto(del);
             } else {
                 meta.setInto(del);
+                del.compile();
             }
-            del.compile();
             
             OpenJPAQuery q = new QueryImpl(this, _ret, del).setId(qid);
             String[] hints = meta.getHintKeys();

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java?rev=742601&r1=742600&r2=742601&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java Mon Feb  9 16:29:37 2009
@@ -665,17 +665,19 @@
         QueryStatistics stats = cache.getStatistics();
         if (alreadyCached && LANG_PREPARED_SQL.equals(lang)) {
             PreparedQuery pq = _em.getPreparedQuery(_id);
-            try {
-                Map rep = pq.reparametrize(params, _em.getBroker());
-                params.clear();
-                params.putAll(rep);
-            } catch (UserException ue) {
-                invalidatePreparedQuery();
-                Log log = _em.getConfiguration().getLog(
-                    OpenJPAConfiguration.LOG_RUNTIME);
-                if (log.isWarnEnabled())
-                    log.warn(ue.getMessage());
-                return false;
+            if (pq.isInitialized()) {
+                try {
+                    Map rep = pq.reparametrize(params, _em.getBroker());
+                    params.clear();
+                    params.putAll(rep);
+                } catch (UserException ue) {
+                    invalidatePreparedQuery();
+                    Log log = _em.getConfiguration().getLog(
+                        OpenJPAConfiguration.LOG_RUNTIME);
+                    if (log.isWarnEnabled())
+                        log.warn(ue.getMessage());
+                    return false;
+                }
             }
             stats.recordExecution(pq.getOriginalQuery(), alreadyCached);
         } else {