mirror of https://github.com/apache/openjpa.git
OPENJPA-2733 subquery parameters are incorrectly assigned
patch submitted by Pawel Veselov - thanks!
This commit is contained in:
parent
0d9645781e
commit
80736f6e9d
|
@ -61,6 +61,7 @@ public class OrderedMap<K, V> implements Map<K, V>, Serializable {
|
|||
|
||||
@Override
|
||||
public void clear() {
|
||||
_del.clear();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue