openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject [openjpa] 03/04: OPENJPA-2733 subquery parameters are incorrectly assigned
Date Thu, 14 Feb 2019 14:09:51 GMT
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

commit 80736f6e9d38dfb180c89cec6cb2916341165a5c
Author: Mark Struberg <struberg@apache.org>
AuthorDate: Thu Feb 14 14:29:11 2019 +0100

    OPENJPA-2733 subquery parameters are incorrectly assigned
    
    patch submitted by Pawel Veselov - thanks!
---
 .../org/apache/openjpa/lib/util/OrderedMap.java    |  1 +
 .../persistence/criteria/TestSubqueries.java       | 73 +++++++++++++++++++---
 .../persistence/criteria/CriteriaQueryImpl.java    | 11 ++--
 .../openjpa/persistence/criteria/SubqueryImpl.java |  7 ++-
 4 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/OrderedMap.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/OrderedMap.java
index 0953dd3..79148f9 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/OrderedMap.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/OrderedMap.java
@@ -61,6 +61,7 @@ public class OrderedMap<K, V> implements Map<K, V>, Serializable
{
 
     @Override
     public void clear() {
+        _del.clear();
     }
 
 
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 d353d9a..f4e8adb 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
@@ -20,15 +20,10 @@ package org.apache.openjpa.persistence.criteria;
 
 import java.sql.Timestamp;
 
+import javax.persistence.Parameter;
 import javax.persistence.Tuple;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Expression;
-import javax.persistence.criteria.Join;
-import javax.persistence.criteria.JoinType;
-import javax.persistence.criteria.ListJoin;
-import javax.persistence.criteria.Root;
-import javax.persistence.criteria.SetJoin;
-import javax.persistence.criteria.Subquery;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.*;
 
 public class TestSubqueries extends CriteriaTest {
 
@@ -585,4 +580,66 @@ public class TestSubqueries extends CriteriaTest {
                 Customer.CreditRating.POOR))));
         assertEquivalence(q, query);
     }
+
+    public void testSubquery24() {
+
+        em.getTransaction().begin();
+
+        em.createQuery("delete from Order o where o.customer.name = 'Capricorn'").executeUpdate();
+        em.createQuery("delete from Order o").executeUpdate();
+        em.createQuery("delete from Customer c where c.name = 'Capricorn'").executeUpdate();
+
+        em.flush();
+
+        Customer c1 = new Customer();
+        c1.setAccountNum(156);
+        c1.setFirstName("John");
+        c1.setLastName("Doe");
+        c1.setName("Capricorn");
+        em.persist(c1);
+
+        Order o1 = new Order();
+        o1.setCustomer(c1);
+        em.persist(o1);
+        o1 = new Order();
+        o1.setCustomer(c1);
+        em.persist(o1);
+
+        em.flush();
+
+        // em.getTransaction().commit();
+
+        // System.out.println("CUSTOMERS: "+em.createQuery("select count(c) from Customer
c").getFirstResult());
+        // System.out.println("ORDERS: "+em.createQuery("select count(c) from Order c").getFirstResult());
+
+        CriteriaQuery<Long> q = cb.createQuery(Long.class);
+        Root<Customer> root = q.from(Customer.class);
+        q.select(root.get(Customer_.accountNum));
+
+        ParameterExpression<String> testParam = cb.parameter(String.class, "param1");
+
+        Subquery<Customer> sq = q.subquery(Customer.class);
+        Root<Order> sqRoot = sq.from(Order.class);
+        sq.where(cb.and(
+                cb.equal(cb.parameter(String.class, "param2"), sqRoot.get(Order_.customer).get(Customer_.lastName)),
+                cb.equal(testParam, sqRoot.get(Order_.customer).get(Customer_.name))
+                ));
+        sq.select(sqRoot.get(Order_.customer));
+
+        q.where(cb.and(
+                cb.equal(testParam, root.get(Customer_.name)),
+                cb.in(root).value(sq)
+        ));
+
+        // em.createQuery(q).getResultList();
+        TypedQuery<Long> tq = em.createQuery(q);
+        tq.setParameter("param1", "Capricorn");
+        tq.setParameter("param2", "Doe");
+
+        assertEquals(1, tq.getResultList().size());
+
+        em.getTransaction().rollback();
+
+    }
+
 }
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 034c784..7ea8a3f 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
@@ -115,11 +115,14 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>,
AliasContext {
      * @param model the metamodel defines the scope of all persistent entity references.
      * @param delegator the subquery which will delegate to this receiver.
      */
-    CriteriaQueryImpl(MetamodelImpl model, SubqueryImpl<T> delegator) {
+    CriteriaQueryImpl(MetamodelImpl model, SubqueryImpl<T> delegator, OrderedMap params)
{
         this._model = model;
         this._resultClass = delegator.getJavaType();
         _delegator = delegator;
         _aliases = getAliases();
+        if (params != null) {
+            this._params = params;
+        }
     }
 
     /**
@@ -225,8 +228,6 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>,
AliasContext {
      * Registers the given parameter.
      */
     void registerParameter(ParameterExpressionImpl<?> p) {
-        if (_params == null)
-            _params = new OrderedMap/*<ParameterExpression<?>, Class<?>*/();
         if (!_params.containsKey(p)) {
             p.setIndex(_params.size());
             _params.put(p, p.getJavaType());
@@ -431,7 +432,7 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>,
AliasContext {
      */
     public OrderedMap<Object, Class<?>> getParameterTypes() {
         collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
-        return _params == null ? StoreQuery.EMPTY_ORDERED_PARAMS : _params;
+        return _params;
     }
 
     /**
@@ -654,7 +655,7 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>,
AliasContext {
 
     void invalidateCompilation() {
         _compiled = false;
-        _params   = null;
+        _params.clear();
     }
 
     /**
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
index 58a5671..e8abe19 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
@@ -43,6 +43,7 @@ import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.kernel.exps.Value;
 import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
+import org.apache.openjpa.lib.util.OrderedMap;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.ValueMetaData;
@@ -78,14 +79,18 @@ class SubqueryImpl<T> extends ExpressionImpl<T> implements
Subquery<T> {
     SubqueryImpl(Class<T> cls, AbstractQuery<?> parent) {
         super(cls);
         _parent = parent;
+        OrderedMap params;
         if (parent instanceof CriteriaQueryImpl) {
             _model = ((CriteriaQueryImpl<?>)parent).getMetamodel();
+            params = ((CriteriaQueryImpl<?>)parent).getParameterTypes();
         } else if (parent instanceof SubqueryImpl) {
             _model = ((SubqueryImpl<?>)parent).getMetamodel();
+            params = ((SubqueryImpl<?>)parent).getInnermostParent().getParameterTypes();
         } else {
             _model = null;
+            params = null;
         }
-        _delegate = new CriteriaQueryImpl<>(_model, this);
+        _delegate = new CriteriaQueryImpl<>(_model, this, params);
     }
 
     /**


Mime
View raw message