[openjpa] branch master updated: OPENJPA-2733 OPENJPA-2785 fix broken spring data usage.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[openjpa] branch master updated: OPENJPA-2733 OPENJPA-2785 fix broken spring data usage.

struberg
This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git


The following commit(s) were added to refs/heads/master by this push:
     new f9b5968  OPENJPA-2733 OPENJPA-2785 fix broken spring data usage.
f9b5968 is described below

commit f9b59689d45fdc5615da6779ad097173e729616b
Author: Mark Struberg <[hidden email]>
AuthorDate: Wed Apr 10 16:05:21 2019 +0200

    OPENJPA-2733 OPENJPA-2785 fix broken spring data usage.
   
    spring-data potentially does something unspecified.
    This hack now prevents duplicate ParameterExpressions with the same name
    while not having to implement equals + hashCode for it - which makes Spring happy.
---
 .../persistence/criteria/TestSubqueries.java       |  4 +++
 .../persistence/criteria/CriteriaQueryImpl.java    | 14 +++++++--
 .../criteria/ParameterExpressionImpl.java          | 35 +++++++++++++++-------
 3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestSubqueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestSubqueries.java
index b2547a8..2dce0cf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestSubqueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestSubqueries.java
@@ -618,6 +618,10 @@ public class TestSubqueries extends CriteriaTest {
         cleanCustomerAndOrder();
     }
 
+    /**
+     * Test 2 different ParameterExpression instances which both have the same name.
+     * They should
+     */
     public void testSubquery25() {
         em.getTransaction().begin();
 
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
index bd36acd..7ece189 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
@@ -224,10 +224,18 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasContext {
      * Registers the given parameter.
      */
     void registerParameter(ParameterExpressionImpl<?> p) {
-        if (!_params.containsKey(p)) {
-            p.setIndex(_params.size());
-            _params.put(p, p.getJavaType());
+        for (Object k : _params.keySet()) {
+            if (p.paramEquals(k)) {
+                // If a named ParameterExpressin did already get registered
+                // with that exact name, then we do ignore it.
+                // If we do a query.setParameter("someParamName", Bla)
+                // then it must uniquely identify a Parameter.
+                return;
+            }
         }
+
+        p.setIndex(_params.size());
+        _params.put(p, p.getJavaType());
     }
 
     @Override
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
index 89dda1e..77b57d1 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
@@ -24,6 +24,7 @@ import javax.persistence.criteria.ParameterExpression;
 
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.kernel.exps.Value;
+import org.apache.openjpa.lib.util.OrderedMap;
 import org.apache.openjpa.util.InternalException;
 
 /**
@@ -109,13 +110,25 @@ class ParameterExpressionImpl<T> extends ExpressionImpl<T>
             : factory.newParameter(paramKey, clzz);
 
         int index = _name != null
-            ? q.getParameterTypes().indexOf(this)
+            ? findIndexWithSameName(q)
             : _index;
         param.setIndex(index);
 
         return param;
     }
 
+    private int findIndexWithSameName(CriteriaQueryImpl<?> q) {
+        OrderedMap<Object, Class<?>> parameterTypes = q.getParameterTypes();
+        int i = 0;
+        for (Object k : parameterTypes.keySet()) {
+            if (paramEquals(k)) {
+                return i;
+            }
+            i++;
+        }
+        return -1;
+    }
+
     @Override
     public StringBuilder asValue(AliasContext q) {
         return Expressions.asValue(q, ":", _name == null ? "param" : _name);
@@ -126,8 +139,7 @@ class ParameterExpressionImpl<T> extends ExpressionImpl<T>
         return getJavaType();
     }
 
-    @Override
-    public boolean equals(Object o) {
+    public boolean paramEquals(Object o) {
         if (this == o)
             return true;
 
@@ -150,14 +162,15 @@ class ParameterExpressionImpl<T> extends ExpressionImpl<T>
     }
 
     @Override
-    public int hashCode() {
-        int result = _name != null ? _name.hashCode() : 0;
-        if (_name == null) {
-            // if name is given, then we ignore the index
-            result = 31 * result + _index;
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
         }
-        result = 31 * result + (getParameterType() != null ? getParameterType().hashCode() : 0);
-        result = 31 * result + (value != null ? value.hashCode() : 0);
-        return result;
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
     }
 }