diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java index ff0c0bdec..4af5dd23c 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java @@ -25,6 +25,7 @@ import org.apache.openjpa.persistence.test.SQLListenerTestCase; */ public class TestTypesafeCriteria extends SQLListenerTestCase { CriteriaBuilder cb; + CriteriaQuery c; EntityManager em; public void setUp() { @@ -32,6 +33,8 @@ public class TestTypesafeCriteria extends SQLListenerTestCase { setDictionary(); cb = (CriteriaBuilder)emf.getQueryBuilder(); em = emf.createEntityManager(); + + c = cb.create(); } void setDictionary() { @@ -50,6 +53,14 @@ public class TestTypesafeCriteria extends SQLListenerTestCase { assertEquivalence(c, jpql); } + public void testImplicitRoot() { + String jpql = "select a from Account a"; + CriteriaQuery c = cb.create(); + c.from(Account.class); + + assertEquivalence(c, jpql); + } + public void testEqual() { String jpql = "select a from Account a where a.balance=100"; @@ -98,6 +109,13 @@ public class TestTypesafeCriteria extends SQLListenerTestCase { assertEquivalence(c, jpql); } + public void testInPredicate() { + String jpql = "select a from Account a where a.owner in ('X','Y','Z')"; + CriteriaQuery c = cb.create(); + Root account = c.from(Account.class); + c.where(cb.in(account.get(Account_.owner)).value("X").value("Y").value("Z")); + assertEquivalence(c, jpql); + } public void testBinaryPredicate() { String jpql = "select a from Account a where a.balance>100 and a.balance<200"; diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java index 731ed9c1f..f9c17429d 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java @@ -23,6 +23,7 @@ import java.util.Collection; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.QueryBuilder.In; import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.kernel.exps.Value; @@ -60,32 +61,37 @@ public abstract class ExpressionImpl extends SelectionImpl } public Predicate in(Object... values) { - // TODO Auto-generated method stub - throw new AbstractMethodError(); + In result = new Expressions.In(this); + for (Object v : values) + result.value((X)v); + return result; } public Predicate in(Expression... values) { - // TODO Auto-generated method stub - throw new AbstractMethodError(); + In result = new Expressions.In(this); + for (Expression e : values) + result.value((Expression)e); + return result; } public Predicate in(Collection values) { - // TODO Auto-generated method stub - throw new AbstractMethodError(); + In result = new Expressions.In(this); + for (Object e : values) + result.value((X)e); + return result; } public Predicate in(Expression values) { - // TODO Auto-generated method stub - throw new AbstractMethodError(); + In result = new Expressions.In(this); + result.value((Expression)values); + return result; } public Predicate isNotNull() { - // TODO Auto-generated method stub - throw new AbstractMethodError(); + return new Expressions.IsNotNull(this); } public Predicate isNull() { - // TODO Auto-generated method stub - throw new AbstractMethodError(); + return new Expressions.IsNull(this); } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java index 43ea0a5f3..bba278004 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.List; import javax.persistence.criteria.Expression; +import javax.persistence.criteria.Predicate; import javax.persistence.criteria.QueryBuilder; import javax.persistence.criteria.QueryBuilder.Trimspec; @@ -700,12 +701,45 @@ public class Expressions { } } - public static class In extends PredicateImpl + public static class IsNull extends PredicateImpl { + ExpressionImpl e; + public IsNull(ExpressionImpl e) { + super(); + this.e = e; + } + + @Override + org.apache.openjpa.kernel.exps.Expression toKernelExpression( + ExpressionFactory factory, MetamodelImpl model) { + return factory.equal( + Expressions.toValue(e, factory, model), + factory.getNull()); + } + } + + public static class IsNotNull extends PredicateImpl { + ExpressionImpl e; + public IsNotNull(ExpressionImpl e) { + super(); + this.e = e; + } + + @Override + org.apache.openjpa.kernel.exps.Expression toKernelExpression( + ExpressionFactory factory, MetamodelImpl model) { + return factory.notEqual( + Expressions.toValue(e, factory, model), + factory.getNull()); + } + } + + + public static class In extends PredicateImpl.Or implements QueryBuilder.In { - private List> values = - new ArrayList>(); + ExpressionImpl e; public In(Expression e) { - super(null); + super((Predicate[])null); + this.e = (ExpressionImpl)e; } public Expression getExpression() { @@ -713,12 +747,22 @@ public class Expressions { } public In value(T value) { - return value(new Constant(value)); + add(new Expressions.Equal(e,value)); + return this; } public In value(Expression value) { - values.add(value); + add(new Expressions.Equal(e,value)); return this; } + + @Override + org.apache.openjpa.kernel.exps.Expression toKernelExpression( + ExpressionFactory factory, MetamodelImpl model) { + IsNotNull notNull = new Expressions.IsNotNull(e); + return factory.and( + super.toKernelExpression(factory, model), + notNull.toKernelExpression(factory, model)); + } } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java index e7a9b7a05..2aafa9492 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java @@ -44,8 +44,10 @@ public class PredicateImpl extends ExpressionImpl protected PredicateImpl(BooleanOperator op, Predicate...restrictions) { this(op); - for (Predicate p : restrictions) - add((PredicateImpl)p); + if (restrictions != null) { + for (Predicate p : restrictions) + add((PredicateImpl)p); + } } public PredicateImpl add(Expression s) { @@ -70,7 +72,8 @@ public class PredicateImpl extends ExpressionImpl public PredicateImpl negate() { PredicateImpl not = new PredicateImpl(_op); not._negated = true; - not._exps = new ArrayList>(this._exps); + if (_exps != null) + not._exps = new ArrayList>(this._exps); not._op = this._op; return not; } @@ -90,13 +93,14 @@ public class PredicateImpl extends ExpressionImpl org.apache.openjpa.kernel.exps.Expression ke2 = e2.toKernelExpression(factory, model); org.apache.openjpa.kernel.exps.Expression result = - _op == BooleanOperator.AND ? - factory.and(ke1,ke2) : factory.or(ke1, ke2); + _op == BooleanOperator.AND + ? factory.and(ke1,ke2) : factory.or(ke1, ke2); for (int i = 2; i < _exps.size(); i++) { ExpressionImpl e = (ExpressionImpl)_exps.get(i); - result = factory.and(result, - e.toKernelExpression(factory, model)); + result = _op == BooleanOperator.AND + ? factory.and(result, e.toKernelExpression(factory, model)) + : factory.or(result, e.toKernelExpression(factory, model)); } return _negated ? factory.not(result) : result; } @@ -119,7 +123,7 @@ public class PredicateImpl extends ExpressionImpl } public Or(Predicate...restrictions) { - super(BooleanOperator.AND, restrictions); + super(BooleanOperator.OR, restrictions); } } }