mirror of https://github.com/apache/openjpa.git
OPENJPA-1013: parameter support for Criteria Query
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@775997 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7b581bf651
commit
76764564b1
|
@ -55,17 +55,17 @@ public abstract class AbstractExpressionBuilder {
|
|||
protected static final int EX_UNSUPPORTED = 2;
|
||||
|
||||
// common implicit type settings
|
||||
protected static final Class<Object> TYPE_OBJECT = Object.class;
|
||||
protected static final Class<String> TYPE_STRING = String.class;
|
||||
protected static final Class<Character> TYPE_CHAR_OBJ = Character.class;
|
||||
protected static final Class<Number> TYPE_NUMBER = Number.class;
|
||||
protected static final Class<Collection> TYPE_COLLECTION = Collection.class;
|
||||
protected static final Class<Map> TYPE_MAP = Map.class;
|
||||
public static final Class<Object> TYPE_OBJECT = Object.class;
|
||||
public static final Class<String> TYPE_STRING = String.class;
|
||||
public static final Class<Character> TYPE_CHAR_OBJ = Character.class;
|
||||
public static final Class<Number> TYPE_NUMBER = Number.class;
|
||||
public static final Class<Collection> TYPE_COLLECTION = Collection.class;
|
||||
public static final Class<Map> TYPE_MAP = Map.class;
|
||||
|
||||
// contains types for setImplicitTypes
|
||||
protected static final int CONTAINS_TYPE_ELEMENT = 1;
|
||||
protected static final int CONTAINS_TYPE_KEY = 2;
|
||||
protected static final int CONTAINS_TYPE_VALUE = 3;
|
||||
public static final int CONTAINS_TYPE_ELEMENT = 1;
|
||||
public static final int CONTAINS_TYPE_KEY = 2;
|
||||
public static final int CONTAINS_TYPE_VALUE = 3;
|
||||
|
||||
private static final Localizer _loc = Localizer.forPackage
|
||||
(AbstractExpressionBuilder.class);
|
||||
|
@ -366,7 +366,7 @@ public abstract class AbstractExpressionBuilder {
|
|||
/**
|
||||
* Perform conversions to make values compatible.
|
||||
*/
|
||||
private void convertTypes(Value val1, Value val2) {
|
||||
public static void convertTypes(Value val1, Value val2) {
|
||||
Class<?> t1 = val1.getType();
|
||||
Class<?> t2 = val2.getType();
|
||||
|
||||
|
@ -415,7 +415,7 @@ public abstract class AbstractExpressionBuilder {
|
|||
/**
|
||||
* Perform conversions to make values compatible.
|
||||
*/
|
||||
private void convertTypesQuotedNumbers(Value val1, Value val2) {
|
||||
public static void convertTypesQuotedNumbers(Value val1, Value val2) {
|
||||
Class<?> t1 = val1.getType();
|
||||
Class<?> t2 = val2.getType();
|
||||
|
||||
|
@ -457,7 +457,7 @@ public abstract class AbstractExpressionBuilder {
|
|||
/**
|
||||
* Return true if given class can be used as a number.
|
||||
*/
|
||||
private static boolean isNumeric(Class<?> type) {
|
||||
public static boolean isNumeric(Class<?> type) {
|
||||
type = Filters.wrap(type);
|
||||
return Number.class.isAssignableFrom(type)
|
||||
|| type == Character.TYPE || type == TYPE_CHAR_OBJ;
|
||||
|
|
|
@ -413,33 +413,32 @@ public class TestTypesafeCriteria extends SQLListenerTestCase {
|
|||
assertEquivalence(q, jpql);
|
||||
}
|
||||
|
||||
@AllowFailure
|
||||
public void testParameters1() {
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = :stat";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Customer> c = q.from(Customer.class);
|
||||
Parameter<Integer> param = cb.parameter(Integer.class);
|
||||
Parameter<Integer> param = cb.parameter(Integer.class, "stat");
|
||||
q.select(c).where(cb.equal(c.get(Customer_.status), param));
|
||||
|
||||
assertEquivalence(q, jpql, new String[]{"stat"}, new Object[] {1});
|
||||
}
|
||||
|
||||
@AllowFailure
|
||||
public void testParameters2() {
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = :stat AND c.name = :name";
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = :stat AND " +
|
||||
"c.name = :name";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Customer> c = q.from(Customer.class);
|
||||
Parameter<Integer> param1 = cb.parameter(Integer.class, "stat");
|
||||
Parameter<String> param2 = cb.parameter(String.class, "name");
|
||||
q.select(c).where(cb.equal(c.get(Customer_.status), param1),
|
||||
cb.equal(c.get(Customer_.name), param2));
|
||||
q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1),
|
||||
cb.equal(c.get(Customer_.name), param2)));
|
||||
|
||||
assertEquivalence(q, jpql, new String[] { "stat", "name" }, new Object[] { 1, "test" });
|
||||
assertEquivalence(q, jpql, new String[] { "stat", "name" },
|
||||
new Object[] { 1, "test" });
|
||||
}
|
||||
|
||||
@AllowFailure
|
||||
public void testParameters3() {
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = :1";
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = ?1";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Customer> c = q.from(Customer.class);
|
||||
Parameter<Integer> param = cb.parameter(Integer.class);
|
||||
|
@ -447,31 +446,31 @@ public class TestTypesafeCriteria extends SQLListenerTestCase {
|
|||
assertEquivalence(q, jpql, new Object[] { 1 });
|
||||
}
|
||||
|
||||
@AllowFailure
|
||||
public void testParameters4() {
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = :1 AND c.name = :2";
|
||||
String jpql = "SELECT c FROM Customer c Where c.status = ?1 AND " +
|
||||
"c.name = ?2";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Customer> c = q.from(Customer.class);
|
||||
Parameter<Integer> param1 = cb.parameter(Integer.class);
|
||||
Parameter<Integer> param2 = cb.parameter(Integer.class);
|
||||
q.select(c).where(cb.equal(c.get(Customer_.status), param1),
|
||||
cb.equal(c.get(Customer_.name), param2));
|
||||
q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1),
|
||||
cb.equal(c.get(Customer_.name), param2)));
|
||||
assertEquivalence(q, jpql, new Object[] { 1, "test" });
|
||||
}
|
||||
|
||||
// collection-valued input parameter
|
||||
// do not support collection-valued input parameter
|
||||
@AllowFailure
|
||||
public void testParameters5() {
|
||||
String jpql = "SELECT c FROM Customer c Where c.status IN (:coll)";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Customer> c = q.from(Customer.class);
|
||||
Parameter<List> param1 = cb.parameter(List.class);
|
||||
q.select(c).where(cb.equal(c.get(Customer_.status), param1));
|
||||
//q.select(c).where(cb.in(c.get(Customer_.status)).value(params1));
|
||||
List vals = new ArrayList();
|
||||
vals.add(1);
|
||||
vals.add(2);
|
||||
|
||||
assertEquivalence(q, jpql, new String[] {"coll"}, new Object[] {vals});
|
||||
//assertEquivalence(q, jpql, new String[] {"coll"}, new Object[] {vals});
|
||||
}
|
||||
|
||||
@AllowFailure
|
||||
|
|
|
@ -34,10 +34,14 @@ import javax.persistence.criteria.Selection;
|
|||
import javax.persistence.criteria.Subquery;
|
||||
import javax.persistence.metamodel.Entity;
|
||||
|
||||
import org.apache.commons.collections.map.LinkedMap;
|
||||
import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
|
||||
import org.apache.openjpa.kernel.exps.ExpressionFactory;
|
||||
import org.apache.openjpa.kernel.exps.Path;
|
||||
import org.apache.openjpa.kernel.exps.QueryExpressions;
|
||||
import org.apache.openjpa.kernel.exps.Value;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.meta.FieldMetaData;
|
||||
import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
||||
import org.apache.openjpa.persistence.meta.Types;
|
||||
|
||||
|
@ -57,6 +61,7 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
private List<Expression<?>> _groups;
|
||||
private PredicateImpl _having;
|
||||
private Boolean _distinct;
|
||||
private LinkedMap _parameterTypes;
|
||||
|
||||
public CriteriaQueryImpl(MetamodelImpl model) {
|
||||
this._model = model;
|
||||
|
@ -164,6 +169,14 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
return null;
|
||||
}
|
||||
|
||||
public LinkedMap getParameterTypes() {
|
||||
return _parameterTypes;
|
||||
}
|
||||
|
||||
public void setParameterTypes(LinkedMap parameterTypes) {
|
||||
_parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate kernel expressions.
|
||||
*/
|
||||
|
@ -184,11 +197,11 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
// exps.fetchInnerPaths = null; // String[]
|
||||
// exps.fetchPaths = null; // String[]
|
||||
exps.filter = _where == null ? factory.emptyExpression()
|
||||
: _where.toKernelExpression(factory, _model);
|
||||
: _where.toKernelExpression(factory, _model, this);
|
||||
|
||||
evalGrouping(exps, factory);
|
||||
exps.having = _having == null ? factory.emptyExpression()
|
||||
: _having.toKernelExpression(factory, _model);
|
||||
: _having.toKernelExpression(factory, _model, this);
|
||||
|
||||
evalOrdering(exps, factory);
|
||||
// exps.operation = QueryOperations.OP_SELECT;
|
||||
|
@ -199,6 +212,8 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
exps.projections = toValues(factory, getSelectionList());
|
||||
// exps.range = null; // Value[]
|
||||
// exps.resultClass = null; // Class
|
||||
if (_parameterTypes != null)
|
||||
exps.parameterTypes = _parameterTypes;
|
||||
return exps;
|
||||
}
|
||||
|
||||
|
@ -214,7 +229,7 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
OrderImpl order = (OrderImpl)_orders.get(i);
|
||||
//Expression<? extends Comparable> expr = order.getExpression();
|
||||
//exps.ordering[i] = Expressions.toValue(
|
||||
// (ExpressionImpl<?>)expr, factory, _model);
|
||||
// (ExpressionImpl<?>)expr, factory, _model, this);
|
||||
|
||||
//exps.orderingClauses[i] = assemble(firstChild);
|
||||
//exps.orderingAliases[i] = firstChild.text;
|
||||
|
@ -231,7 +246,7 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
for (int i = 0; i < groupByCount; i++) {
|
||||
Expression<?> groupBy = _groups.get(i);
|
||||
exps.grouping[i] = Expressions.toValue(
|
||||
(ExpressionImpl<?>)groupBy, factory, _model);;
|
||||
(ExpressionImpl<?>)groupBy, factory, _model, this);;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,9 +259,68 @@ public class CriteriaQueryImpl implements CriteriaQuery {
|
|||
Value[] result = new Value[sels.size()];
|
||||
int i = 0;
|
||||
for (Selection<?> s : sels) {
|
||||
result[i++] = ((ExpressionImpl<?>)s).toValue(factory, _model);
|
||||
result[i++] = ((ExpressionImpl<?>)s).toValue(factory, _model,
|
||||
this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setImplicitTypes(Value val1, Value val2, Class<?> expected) {
|
||||
Class<?> c1 = val1.getType();
|
||||
Class<?> c2 = val2.getType();
|
||||
boolean o1 = c1 == AbstractExpressionBuilder.TYPE_OBJECT;
|
||||
boolean o2 = c2 == AbstractExpressionBuilder.TYPE_OBJECT;
|
||||
|
||||
if (o1 && !o2) {
|
||||
val1.setImplicitType(c2);
|
||||
if (val1.getMetaData() == null && !val1.isXPath())
|
||||
val1.setMetaData(val2.getMetaData());
|
||||
} else if (!o1 && o2) {
|
||||
val2.setImplicitType(c1);
|
||||
if (val2.getMetaData() == null && !val1.isXPath())
|
||||
val2.setMetaData(val1.getMetaData());
|
||||
} else if (o1 && o2 && expected != null) {
|
||||
// we never expect a pc type, so don't bother with metadata
|
||||
val1.setImplicitType(expected);
|
||||
val2.setImplicitType(expected);
|
||||
} else if (AbstractExpressionBuilder.isNumeric(val1.getType())
|
||||
!= AbstractExpressionBuilder.isNumeric(val2.getType())) {
|
||||
AbstractExpressionBuilder.convertTypes(val1, val2);
|
||||
}
|
||||
|
||||
// as well as setting the types for conversions, we also need to
|
||||
// ensure that any parameters are declared with the correct type,
|
||||
// since the JPA spec expects that these will be validated
|
||||
org.apache.openjpa.kernel.exps.Parameter param =
|
||||
val1 instanceof org.apache.openjpa.kernel.exps.Parameter ?
|
||||
(org.apache.openjpa.kernel.exps.Parameter) val1
|
||||
: val2 instanceof org.apache.openjpa.kernel.exps.Parameter ?
|
||||
(org.apache.openjpa.kernel.exps.Parameter) val2 : null;
|
||||
Path path = val1 instanceof Path ? (Path) val1
|
||||
: val2 instanceof Path ? (Path) val2 : null;
|
||||
|
||||
// we only check for parameter-to-path comparisons
|
||||
if (param == null || path == null || _parameterTypes == null)
|
||||
return;
|
||||
|
||||
FieldMetaData fmd = path.last();
|
||||
if (fmd == null)
|
||||
return;
|
||||
|
||||
//TODO:
|
||||
//if (expected == null)
|
||||
// checkEmbeddable(path);
|
||||
|
||||
Class<?> type = path.getType();
|
||||
if (type == null)
|
||||
return;
|
||||
|
||||
Object paramKey = param.getParameterKey();
|
||||
if (paramKey == null)
|
||||
return;
|
||||
|
||||
// make sure we have already declared the parameter
|
||||
if (_parameterTypes.containsKey(paramKey))
|
||||
_parameterTypes.put(paramKey, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.openjpa.persistence.criteria;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.QueryBuilder.In;
|
||||
|
@ -39,12 +40,14 @@ import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
|||
public abstract class ExpressionImpl<X> extends SelectionImpl<X>
|
||||
implements Expression<X> {
|
||||
|
||||
Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
throw new AbstractMethodError(this.getClass().getName());
|
||||
}
|
||||
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
throw new AbstractMethodError(this.getClass().getName());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.QueryBuilder;
|
||||
|
@ -38,8 +39,8 @@ import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
|||
public class Expressions {
|
||||
|
||||
static Value toValue(ExpressionImpl<?> e, ExpressionFactory factory,
|
||||
MetamodelImpl model) {
|
||||
Value v = e.toValue(factory, model);
|
||||
MetamodelImpl model, CriteriaQuery q) {
|
||||
Value v = e.toValue(factory, model, q);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -107,8 +108,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.abs(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.abs(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,8 +127,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
Value v = factory.count(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
Value v = factory.count(Expressions.toValue(e, factory, model, q));
|
||||
return _distinct ? factory.distinct(v) : v;
|
||||
}
|
||||
}
|
||||
|
@ -137,8 +140,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.avg(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.avg(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,8 +152,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.sqrt(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.sqrt(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,8 +164,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.max(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.max(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,8 +176,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.min(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.min(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,8 +192,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.size(Expressions.toValue(e, factory, model));
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.size(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,8 +205,9 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
return factory.cast(Expressions.toValue(e, factory, model), b);
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.cast(Expressions.toValue(e, factory, model, q), b);
|
||||
}
|
||||
}
|
||||
public static class Concat extends BinarayFunctionalExpression<String> {
|
||||
|
@ -215,10 +224,11 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.concat(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,11 +256,12 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return JPQLExpressionBuilder.convertSubstringArguments(factory,
|
||||
Expressions.toValue(e, factory, model),
|
||||
from == null ? null : from.toValue(factory, model),
|
||||
len == null ? null : len.toValue(factory, model));
|
||||
Expressions.toValue(e, factory, model, q),
|
||||
from == null ? null : from.toValue(factory, model, q),
|
||||
len == null ? null : len.toValue(factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +297,8 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
Boolean spec = null;
|
||||
if (ts != null) {
|
||||
switch (ts) {
|
||||
|
@ -296,8 +308,8 @@ public class Expressions {
|
|||
}
|
||||
}
|
||||
return factory.trim(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model), spec);
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q), spec);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,12 +336,13 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return (e2 == null)
|
||||
? factory.sum(Expressions.toValue(e1, factory, model))
|
||||
? factory.sum(Expressions.toValue(e1, factory, model, q))
|
||||
: factory.add(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,10 +362,11 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.multiply(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,10 +386,11 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.subtract(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,10 +411,11 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.divide(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,10 +433,11 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.mod(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,7 +447,8 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.getCurrentDate();
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +459,8 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.getCurrentTime();
|
||||
}
|
||||
}
|
||||
|
@ -453,7 +472,8 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.getCurrentTimestamp();
|
||||
}
|
||||
}
|
||||
|
@ -475,21 +495,21 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
boolean isTypeExpr = false;
|
||||
Value val1 = Expressions.toValue(e1, factory, model);
|
||||
Value val2 = Expressions.toValue(e2, factory, model);
|
||||
Value val1 = Expressions.toValue(e1, factory, model, q);
|
||||
Value val2 = Expressions.toValue(e2, factory, model, q);
|
||||
if (e1 instanceof PathImpl) {
|
||||
PathImpl path = (PathImpl)e1;
|
||||
isTypeExpr = path.isTypeExpr();
|
||||
if (isTypeExpr) {
|
||||
((Constant)e2).setTypeLit(isTypeExpr);
|
||||
val2 = Expressions.toValue(e2, factory, model);
|
||||
val2 = Expressions.toValue(e2, factory, model, q);
|
||||
Class clzz = (Class)((Literal)val2).getValue();
|
||||
val2.setMetaData(((Types.Managed)model.type(clzz)).meta);
|
||||
}
|
||||
}
|
||||
|
||||
((CriteriaQueryImpl)q).setImplicitTypes(val1, val2, null);
|
||||
if (!negate)
|
||||
return factory.equal(val1, val2);
|
||||
else
|
||||
|
@ -508,10 +528,10 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
return factory.greaterThan(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,10 +546,10 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
return factory.greaterThanEqual(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,10 +565,10 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
return factory.lessThan(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,10 +583,10 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
return factory.lessThanEqual(
|
||||
Expressions.toValue(e1, factory, model),
|
||||
Expressions.toValue(e2, factory, model));
|
||||
Expressions.toValue(e1, factory, model, q),
|
||||
Expressions.toValue(e2, factory, model, q));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -601,7 +621,8 @@ public class Expressions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
if (!typeLit)
|
||||
return factory.newLiteral(arg, 1);
|
||||
else
|
||||
|
@ -625,13 +646,14 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
if (!negate)
|
||||
return factory.isEmpty(
|
||||
Expressions.toValue(collection, factory, model));
|
||||
Expressions.toValue(collection, factory, model, q));
|
||||
else
|
||||
return factory.isNotEmpty(
|
||||
Expressions.toValue(collection, factory, model));
|
||||
Expressions.toValue(collection, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,10 +683,11 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.contains(
|
||||
Expressions.toValue(collection, factory, model),
|
||||
Expressions.toValue(element, factory, model));
|
||||
Expressions.toValue(collection, factory, model, q),
|
||||
Expressions.toValue(element, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -704,11 +727,12 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
return factory.matches(
|
||||
Expressions.toValue(str, factory, model),
|
||||
Expressions.toValue(pattern, factory, model), "_", "%",
|
||||
Expressions.toValue(escapeChar, factory, model).toString());
|
||||
Expressions.toValue(str, factory, model, q),
|
||||
Expressions.toValue(pattern, factory, model, q), "_", "%",
|
||||
Expressions.toValue(escapeChar, factory, model, q).toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -737,12 +761,13 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
public org.apache.openjpa.kernel.exps.Value toValue(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
Value[] vs = new Value[values.size()];
|
||||
int i = 0;
|
||||
for (Expression<?> e : values)
|
||||
vs[i++] = Expressions.toValue((ExpressionImpl<?>)e,
|
||||
factory, model);
|
||||
factory, model, q);
|
||||
return factory.coalesceExpression(vs);
|
||||
}
|
||||
}
|
||||
|
@ -756,9 +781,9 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
return factory.equal(
|
||||
Expressions.toValue(e, factory, model),
|
||||
Expressions.toValue(e, factory, model, q),
|
||||
factory.getNull());
|
||||
}
|
||||
}
|
||||
|
@ -772,9 +797,9 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
return factory.notEqual(
|
||||
Expressions.toValue(e, factory, model),
|
||||
Expressions.toValue(e, factory, model, q),
|
||||
factory.getNull());
|
||||
}
|
||||
}
|
||||
|
@ -804,11 +829,11 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
IsNotNull notNull = new Expressions.IsNotNull(e);
|
||||
return factory.and(
|
||||
super.toKernelExpression(factory, model),
|
||||
notNull.toKernelExpression(factory, model));
|
||||
super.toKernelExpression(factory, model, q),
|
||||
notNull.toKernelExpression(factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,21 +882,22 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
public org.apache.openjpa.kernel.exps.Value toValue(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
int size = whens.size();
|
||||
org.apache.openjpa.kernel.exps.Expression[] exps =
|
||||
new org.apache.openjpa.kernel.exps.Expression[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
org.apache.openjpa.kernel.exps.Expression expr =
|
||||
((Expressions.BinaryLogicalExpression)whens.get(i)).
|
||||
toKernelExpression(factory, model);
|
||||
toKernelExpression(factory, model, q);
|
||||
Value action = Expressions.toValue(
|
||||
(ExpressionImpl<?>)thens.get(i), factory, model);
|
||||
(ExpressionImpl<?>)thens.get(i), factory, model, q);
|
||||
exps[i] = factory.whenCondition(expr, action);
|
||||
}
|
||||
|
||||
Value other = Expressions.toValue(
|
||||
(ExpressionImpl<?>)otherwise, factory, model);
|
||||
(ExpressionImpl<?>)otherwise, factory, model, q);
|
||||
return factory.generalCaseExpression(exps, other);
|
||||
}
|
||||
}
|
||||
|
@ -929,9 +955,10 @@ public class Expressions {
|
|||
|
||||
@Override
|
||||
public org.apache.openjpa.kernel.exps.Value toValue(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
Value caseOperandExpr = Expressions.toValue(
|
||||
(ExpressionImpl<?>)caseOperand, factory, model);
|
||||
(ExpressionImpl<?>)caseOperand, factory, model, q);
|
||||
int size = whens.size();
|
||||
org.apache.openjpa.kernel.exps.Expression[] exps =
|
||||
new org.apache.openjpa.kernel.exps.Expression[size];
|
||||
|
@ -940,12 +967,12 @@ public class Expressions {
|
|||
//TODO: Boolean literal, String literal
|
||||
val = factory.newLiteral(whens.get(i), Literal.TYPE_NUMBER);
|
||||
Value action = Expressions.toValue(
|
||||
(ExpressionImpl<?>)thens.get(i), factory, model);
|
||||
(ExpressionImpl<?>)thens.get(i), factory, model, q);
|
||||
exps[i] = factory.whenScalar(val, action);
|
||||
}
|
||||
|
||||
Value other = Expressions.toValue(
|
||||
(ExpressionImpl<?>)otherwise, factory, model);
|
||||
(ExpressionImpl<?>)otherwise, factory, model, q);
|
||||
return factory.simpleCaseExpression(caseOperandExpr, exps, other);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,14 @@
|
|||
*/
|
||||
package org.apache.openjpa.persistence.criteria;
|
||||
|
||||
import java.util.Collection;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import org.apache.commons.collections.map.LinkedMap;
|
||||
import org.apache.openjpa.kernel.exps.ExpressionFactory;
|
||||
import org.apache.openjpa.kernel.exps.Value;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
||||
|
||||
/**
|
||||
* Parameter of a criteria query.
|
||||
|
@ -48,4 +55,40 @@ public class ParameterImpl<T> extends ExpressionImpl<T> implements Parameter<T>{
|
|||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
boolean positional = false;
|
||||
LinkedMap parameterTypes = ((CriteriaQueryImpl)q).getParameterTypes();
|
||||
if (parameterTypes == null) {
|
||||
parameterTypes = new LinkedMap(6);
|
||||
((CriteriaQueryImpl)q).setParameterTypes(parameterTypes);
|
||||
}
|
||||
if (name == null) {
|
||||
position = parameterTypes.size() + 1;
|
||||
positional = true;
|
||||
}
|
||||
|
||||
Object paramKey = name == null ? Integer.valueOf(position) : name;
|
||||
if (!parameterTypes.containsKey(paramKey))
|
||||
parameterTypes.put(paramKey, Object.class);
|
||||
|
||||
ClassMetaData meta = null;
|
||||
Class clzz = getJavaType();
|
||||
int index;
|
||||
if (positional)
|
||||
index = position - 1;
|
||||
else
|
||||
// otherwise the index is just the current size of the params
|
||||
index = parameterTypes.indexOf(paramKey);
|
||||
|
||||
boolean isCollectionValued = Collection.class.isAssignableFrom(clzz);
|
||||
org.apache.openjpa.kernel.exps.Parameter param = isCollectionValued
|
||||
? factory.newCollectionValuedParameter(paramKey, Object.class)
|
||||
: factory.newParameter(paramKey, Object.class);
|
||||
param.setMetaData(meta);
|
||||
param.setIndex(index);
|
||||
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.apache.openjpa.persistence.criteria;
|
||||
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.metamodel.AbstractCollection;
|
||||
|
@ -65,12 +66,13 @@ public class PathImpl<X> extends ExpressionImpl<X> implements Path<X> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQuery q) {
|
||||
Value var = null;
|
||||
if (_parent != null) {
|
||||
org.apache.openjpa.kernel.exps.Path path =
|
||||
(org.apache.openjpa.kernel.exps.Path)
|
||||
_parent.toValue(factory, model);
|
||||
_parent.toValue(factory, model, q);
|
||||
path.get(member.fmd, false);
|
||||
var = path;
|
||||
} else {
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.openjpa.persistence.criteria;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
|
||||
|
@ -80,18 +81,18 @@ public class PredicateImpl extends ExpressionImpl<Boolean>
|
|||
|
||||
@Override
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
|
||||
ExpressionFactory factory, MetamodelImpl model) {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
|
||||
if (_exps == null || _exps.isEmpty())
|
||||
return factory.emptyExpression();
|
||||
if (_exps.size() == 1)
|
||||
return ((ExpressionImpl<?>)_exps.get(0))
|
||||
.toKernelExpression(factory, model);
|
||||
.toKernelExpression(factory, model, q);
|
||||
ExpressionImpl<?> e1 = (ExpressionImpl<?>)_exps.get(0);
|
||||
ExpressionImpl<?> e2 = (ExpressionImpl<?>)_exps.get(1);
|
||||
org.apache.openjpa.kernel.exps.Expression ke1 =
|
||||
e1.toKernelExpression(factory, model);
|
||||
e1.toKernelExpression(factory, model, q);
|
||||
org.apache.openjpa.kernel.exps.Expression ke2 =
|
||||
e2.toKernelExpression(factory, model);
|
||||
e2.toKernelExpression(factory, model, q);
|
||||
org.apache.openjpa.kernel.exps.Expression result =
|
||||
_op == BooleanOperator.AND
|
||||
? factory.and(ke1,ke2) : factory.or(ke1, ke2);
|
||||
|
@ -99,8 +100,8 @@ public class PredicateImpl extends ExpressionImpl<Boolean>
|
|||
for (int i = 2; i < _exps.size(); i++) {
|
||||
ExpressionImpl<?> e = (ExpressionImpl<?>)_exps.get(i);
|
||||
result = _op == BooleanOperator.AND
|
||||
? factory.and(result, e.toKernelExpression(factory, model))
|
||||
: factory.or(result, e.toKernelExpression(factory, model));
|
||||
? factory.and(result, e.toKernelExpression(factory, model, q))
|
||||
: factory.or(result, e.toKernelExpression(factory,model,q));
|
||||
}
|
||||
return _negated ? factory.not(result) : result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue