Author: mikedd
Date: Tue May 10 02:42:30 2011
New Revision: 1101289

URL: http://svn.apache.org/viewvc?rev=1101289&view=rev
Log:
OPENJPA-1995: detect mixed parameter types in JPQL query

Modified:
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
    
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestSetParameter.java

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=1101289&r1=1101288&r2=1101289&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
 Tue May 10 02:42:30 2011
@@ -2469,19 +2469,36 @@ public class JPQLExpressionBuilder
        }
     
     
-    // throws an exception if there are numeric parameters which do not start 
with 1. 
+    // throws an exception if there are numeric parameters which do not start 
with 1.
     private void validateParameters() {
-        if(parameterTypes == null || parameterTypes.isEmpty()) { 
+        if (parameterTypes == null || parameterTypes.isEmpty()) {
             return;
         }
-        
-        Object firstKey = parameterTypes.keySet().iterator().next();
-        if (firstKey != null) { // paranoia
-            if (firstKey instanceof Number) {
-                if (!parameterTypes.keySet().contains(1)) {
-                    throw new 
UserException(_loc.get("missing-positional-parameter", 
resolver.getQueryContext()
+
+        boolean numericParms = false;
+        boolean namedParms = false;
+
+        for (Object key : parameterTypes.keySet()) {
+
+            if (key instanceof Number) {
+                if (namedParms) {
+                    throw new UserException(_loc.get("mixed-parameter-types", 
resolver.getQueryContext()
+                        .getQueryString(), 
parameterTypes.keySet().toString()));
+                }
+                numericParms = true;
+            } else {
+                if (numericParms) {
+                    throw new UserException(_loc.get("mixed-parameter-types", 
resolver.getQueryContext()
                         .getQueryString(), 
parameterTypes.keySet().toString()));
                 }
+                namedParms = true;
+            }
+        }
+
+        if (numericParms) {
+            if (!parameterTypes.keySet().contains(1)) {
+                throw new 
UserException(_loc.get("missing-positional-parameter", 
resolver.getQueryContext()
+                    .getQueryString(), parameterTypes.keySet().toString()));
             }
         }
     }

Modified: 
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties?rev=1101289&r1=1101288&r2=1101289&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
 Tue May 10 02:42:30 2011
@@ -89,3 +89,5 @@ cant-groupby-key-value-embeddable: Group
 no-constructor: NEW constructor operation could not resolve class named "{0}".
 missing-positional-parameter: Query "{0}" did not contain positional parameter 
1. \
     JPQL positional parameters must start at 1. Detected parameters "{1}".
+mixed-parameter-types: Query "{0}" Contains both named and positional 
parameters \
+       this is not allowed by the JPA specification. Detected parameters "{1}".

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestSetParameter.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestSetParameter.java?rev=1101289&r1=1101288&r2=1101289&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestSetParameter.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestSetParameter.java
 Tue May 10 02:42:30 2011
@@ -145,6 +145,18 @@ public class TestSetParameter extends Si
             // expected
         }
         em.close();
+    }   
+    
+    public void testMixedParameterTypesParameter() {
+        EntityManager em = emf.createEntityManager();
+        String query = "UPDATE CompUser e set e.name= :name, e.age = ?1 " + 
"WHERE e.userid = ?3";
+        try {
+            em.createQuery(query);
+            fail("Did not get UserException with invalid JPQL query");
+        } catch (ArgumentException ae) {
+            // expected
+        }
+        em.close();
     }
     
     public CompUser createUser(String name, String cName, int age,


Reply via email to