You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2011/06/10 01:16:09 UTC

svn commit: r1134128 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/meta/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ openjpa-persistence/src/m...

Author: hthomann
Date: Thu Jun  9 23:16:09 2011
New Revision: 1134128

URL: http://svn.apache.org/viewvc?rev=1134128&view=rev
Log:
OPENJPA-1999: Optional support for non-sequential positional parameters - used Rick's provided patch for trunk.

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryConvertPositionalParameters.java   (with props)
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.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
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=1134128&r1=1134127&r2=1134128&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Thu Jun  9 23:16:09 2011
@@ -69,6 +69,7 @@ public class Compatibility {
     private boolean _checkDatabaseForCascadePersistToDetachedEntity = false;
     private boolean _overrideContextClassloader = true;
     private boolean _parseAnnotationsForQueryMode = true;
+    private boolean _convertPositionalParametersToNamed = false;    
     
     /**
      * Whether to require exact identity value types when creating object
@@ -330,6 +331,14 @@ public class Compatibility {
     public boolean getIgnoreDetachedStateFieldForProxySerialization() {
         return _ignoreDetachedStateFieldForProxySerialization;
     }
+    
+    public boolean getConvertPositionalParametersToNamed() {
+        return _convertPositionalParametersToNamed;
+    }
+
+    public void setConvertPositionalParametersToNamed(boolean c) {
+        _convertPositionalParametersToNamed = c;
+    }    
 
     /**
      * Whether OpenJPA should flush changes before detaching or serializing an

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java?rev=1134128&r1=1134127&r2=1134128&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java Thu Jun  9 23:16:09 2011
@@ -2038,7 +2038,8 @@ public class MetaDataRepository implemen
      * Create a new query metadata instance.
      */
     protected QueryMetaData newQueryMetaData(Class<?> cls, String name) {
-        QueryMetaData meta = new QueryMetaData(name);
+        QueryMetaData meta =
+            new QueryMetaData(name, _conf.getCompatibilityInstance().getConvertPositionalParametersToNamed());
         meta.setDefiningType(cls);
         return meta;
     }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java?rev=1134128&r1=1134127&r2=1134128&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java Thu Jun  9 23:16:09 2011
@@ -25,6 +25,8 @@ import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.QueryLanguages;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
 import org.apache.openjpa.lib.meta.SourceTracker;
 import org.apache.openjpa.lib.xml.Commentable;
 
@@ -59,12 +61,14 @@ public class QueryMetaData
     private int _lineNum;  
     private int _colNum;
     private String _srcName; 
+    private boolean _convertPositionalParametersToNamed;
 
     /**
      * Construct with the given name.
      */
-    protected QueryMetaData(String name) {
+    protected QueryMetaData(String name, boolean convertPositionalParametersToNamed) {
         _name = name;
+        _convertPositionalParametersToNamed = convertPositionalParametersToNamed;
     }
 
     /**
@@ -155,6 +159,9 @@ public class QueryMetaData
      * The full query string, or null if none.
      */
     public void setQueryString(String query) {
+        if (query != null && _convertPositionalParametersToNamed && JPQLParser.LANG_JPQL.equals(_language)) {
+            query = query.replaceAll("[\\?]", "\\:_");
+        }
         _query = query;
     }
 

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java?rev=1134128&r1=1134127&r2=1134128&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java Thu Jun  9 23:16:09 2011
@@ -44,7 +44,9 @@ import javax.persistence.Table;
             query="select a from simple a where a.id=:id and a.name=:name"),
     @NamedQuery(name="FindOne",
             query="select s from simple s where s.name = ?1"),
-    @NamedQuery(name="FindAll", query="select s from simple s")
+    @NamedQuery(name="FindAll", query="select s from simple s"),
+    @NamedQuery(name="SelectWithPositionalParameterNonOneStart",
+        query="select a from simple a where a.id=?900 and a.name=?2")
 })
 
 @NamedNativeQueries( { 

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryConvertPositionalParameters.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryConvertPositionalParameters.java?rev=1134128&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryConvertPositionalParameters.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryConvertPositionalParameters.java Thu Jun  9 23:16:09 2011
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * This test was added for OPENJPA-1999. 'Add' support for allowing positional parameters to start at something other
+ * than 1 and allow for missing parameters.
+ */
+public class TestQueryConvertPositionalParameters extends SingleEMFTestCase {
+    EntityManager _em;
+    long _id;
+    String _name;
+
+    @Override
+    public void setUp() {
+        super.setUp(SimpleEntity.class, "openjpa.Compatibility", "ConvertPositionalParametersToNamed=true");
+        _em = emf.createEntityManager();
+        
+        _em.getTransaction().begin();
+        SimpleEntity se = new SimpleEntity();
+        _name = "name--" + System.currentTimeMillis();
+        se.setName(_name);
+        _em.persist(se);
+        _em.getTransaction().commit();
+        _id = se.getId();
+        _em.clear();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (_em.getTransaction().isActive()) {
+            _em.getTransaction().rollback();
+        }
+        _em.close();
+        // TODO Auto-generated method stub
+        super.tearDown();
+    }
+
+    public void testNamedPositionalStartAtNonOne() {
+        SimpleEntity se =
+            _em.createNamedQuery("SelectWithPositionalParameterNonOneStart", SimpleEntity.class).setParameter(900, _id)
+                .setParameter(2, _name).getSingleResult();
+        assertNotNull(se);
+    }
+
+    public void testJPQLPositionalStartAtNonOne() {
+        int idPos = 7;
+        int namePos = 908;
+        SimpleEntity se =
+            _em.createQuery("Select s FROM simple s where s.id=?" + idPos + " and s.name=?" + namePos,
+                SimpleEntity.class).setParameter(idPos, _id).setParameter(namePos, _name).getSingleResult();
+        assertNotNull(se);
+    }
+
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryConvertPositionalParameters.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=1134128&r1=1134127&r2=1134128&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java Thu Jun  9 23:16:09 2011
@@ -1822,8 +1822,8 @@ public class AnnotationPersistenceMetaDa
                 continue;
             }
             meta = getRepository().addQueryMetaData(_cls, query.name());
-            meta.setQueryString(query.query());
             meta.setLanguage(JPQLParser.LANG_JPQL);
+            meta.setQueryString(query.query());
             for (QueryHint hint : query.hints())
                 meta.addHint(hint.name(), hint.value());
             LockModeType lmt = processNamedQueryLockModeType(query);
@@ -1895,8 +1895,8 @@ public class AnnotationPersistenceMetaDa
             }
 
             meta = getRepository().addQueryMetaData(null, query.name());
-            meta.setQueryString(query.query());
             meta.setLanguage(QueryLanguages.LANG_SQL);
+            meta.setQueryString(query.query());
             Class<?> res = query.resultClass();
             if (ImplHelper.isManagedType(getConfiguration(), res))
                 meta.setCandidateType(res);

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=1134128&r1=1134127&r2=1134128&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 Thu Jun  9 23:16:09 2011
@@ -113,7 +113,8 @@ public class EntityManagerImpl
     private EntityManagerFactoryImpl _emf;
     private Map<FetchConfiguration,FetchPlan> _plans = new IdentityHashMap<FetchConfiguration,FetchPlan>(1);
     protected RuntimeExceptionTranslator _ret = PersistenceExceptions.getRollbackTranslator(this);
-
+    private boolean _convertPositionalParams = false;
+    
     public EntityManagerImpl() {
         // for Externalizable
     }
@@ -129,6 +130,9 @@ public class EntityManagerImpl
         _emf = factory;
         _broker = new DelegatingBroker(broker, _ret);
         _broker.setImplicitBehavior(this, _ret);
+        
+        _convertPositionalParams =
+            factory.getConfiguration().getCompatibilityInstance().getConvertPositionalParametersToNamed();
     }
 
     /**
@@ -977,6 +981,10 @@ public class EntityManagerImpl
     public OpenJPAQuery createQuery(String language, String query) {
         assertNotCloseInvoked();
         try {
+            // We need
+            if (query != null && _convertPositionalParams && JPQLParser.LANG_JPQL.equals(language)) {
+                query = query.replaceAll("[\\?]", "\\:_");
+            }
             String qid = query;
             PreparedQuery pq = JPQLParser.LANG_JPQL.equals(language)
                 ? getPreparedQuery(qid) : null;
@@ -1017,11 +1025,10 @@ public class EntityManagerImpl
                 _broker.getClassLoader(), true);
             String qid = meta.getQueryString();
             
-            PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage())
-                ? getPreparedQuery(qid) : null;
-            org.apache.openjpa.kernel.Query del = (pq == null || !pq.isInitialized())
-                ? _broker.newQuery(meta.getLanguage(), meta.getQueryString())
-                : _broker.newQuery(pq.getLanguage(), pq);
+            PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage()) ? getPreparedQuery(qid) : null;
+            org.apache.openjpa.kernel.Query del =
+                (pq == null || !pq.isInitialized()) ? _broker.newQuery(meta.getLanguage(), meta.getQueryString())
+                    : _broker.newQuery(pq.getLanguage(), pq);
             
             if (pq != null) {
                 pq.setInto(del);
@@ -1060,7 +1067,8 @@ public class EntityManagerImpl
     }
 
     protected <T> QueryImpl<T> newQueryImpl(org.apache.openjpa.kernel.Query kernelQuery) {
-        return new QueryImpl<T>(this, _ret, kernelQuery);
+        return new QueryImpl<T>(this, _ret, kernelQuery, _convertPositionalParams
+            && !kernelQuery.getLanguage().equals(QueryLanguages.LANG_SQL));
     }
 
     /**

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=1134128&r1=1134127&r2=1134128&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 Thu Jun  9 23:16:09 2011
@@ -93,6 +93,7 @@ public class QueryImpl<X> implements Ope
     private transient ReentrantLock _lock = null;
 	private HintHandler _hintHandler;
 	private boolean _relaxBindParameterTypeChecking;
+	final private boolean _convertPositionalParams;
 	
 	/**
 	 * Constructor; supply factory exception translator and delegate.
@@ -101,19 +102,21 @@ public class QueryImpl<X> implements Ope
 	 * @param ret Exception translator for this query
 	 * @param query The underlying "kernel" query.
 	 */
-	public QueryImpl(EntityManagerImpl em, RuntimeExceptionTranslator ret, org.apache.openjpa.kernel.Query query) {
-		_em = em;
-		_query = new DelegatingQuery(query, ret);
-		_lock = new ReentrantLock();
-	}
+	public QueryImpl(EntityManagerImpl em, RuntimeExceptionTranslator ret, org.apache.openjpa.kernel.Query query,
+        boolean convertPositionalParams) {
+        _em = em;
+        _query = new DelegatingQuery(query, ret);
+        _lock = new ReentrantLock();
+        _convertPositionalParams = convertPositionalParams;
+    }
 
 	/**
 	 * Constructor; supply factory and delegate.
 	 * 
 	 * @deprecated
 	 */
-	public QueryImpl(EntityManagerImpl em, org.apache.openjpa.kernel.Query query) {
-		this(em, null, query);
+	public QueryImpl(EntityManagerImpl em, org.apache.openjpa.kernel.Query query, boolean convertPositionalParams) {
+		this(em, null, query, convertPositionalParams);
 	}
 
 	/**
@@ -677,6 +680,10 @@ public class QueryImpl<X> implements Ope
      * parameter of the query or if the argument is of incorrect type
      */    
     public OpenJPAQuery<X> setParameter(int pos, Object value) {
+        if (_convertPositionalParams == true) {
+            return setParameter("_"+String.valueOf(pos), value);
+        }
+        
         _query.assertOpen();
         _em.assertNotCloseInvoked();
         _query.lock();
@@ -868,6 +875,9 @@ public class QueryImpl<X> implements Ope
      * the same parameter position is bound already.
      */
     public <T> Parameter<T> getParameter(int pos, Class<T> type) {
+        if (_convertPositionalParams == true) {
+            return getParameter("_"+String.valueOf(pos), type);
+        }
         Parameter<?> param = getParameter(pos);
         if (param.getParameterType().isAssignableFrom(type))
             throw new IllegalArgumentException(param + " does not match the requested type " + type);
@@ -944,6 +954,9 @@ public class QueryImpl<X> implements Ope
      * @throws IllegalArgumentException if the parameter with the given position does not exist
      */
     public Parameter<?> getParameter(int pos) {
+        if(_convertPositionalParams == true){
+            return getParameter("_"+String.valueOf(pos));
+        }
         Parameter<?> param = getDeclaredParameters().get(pos);
         if (param == null)
             throw new IllegalArgumentException(_loc.get("param-missing-pos", 

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=1134128&r1=1134127&r2=1134128&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Thu Jun  9 23:16:09 2011
@@ -1704,8 +1704,8 @@ public class XMLPersistenceMetaDataParse
 
         meta = getRepository().addQueryMetaData(null, name);
         meta.setDefiningType(_cls);
-        meta.setQueryString(attrs.getValue("query"));
         meta.setLanguage(JPQLParser.LANG_JPQL);
+        meta.setQueryString(attrs.getValue("query"));
         String lockModeStr = attrs.getValue("lock-mode");
         LockModeType lmt = processNamedQueryLockModeType(log, lockModeStr, name);
         if (lmt != null) {
@@ -1808,8 +1808,8 @@ public class XMLPersistenceMetaDataParse
 
         meta = getRepository().addQueryMetaData(null, name);
         meta.setDefiningType(_cls);
-        meta.setQueryString(attrs.getValue("query"));
         meta.setLanguage(QueryLanguages.LANG_SQL);
+        meta.setQueryString(attrs.getValue("query"));
         String val = attrs.getValue("result-class");
         if (val != null) {
             Class<?> type = classForName(val);