OPENJPA-2770 ensure equal(xxx, literal(boolean)) works in criteria builder
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 d850c16..5f2f8e5 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
@@ -76,6 +76,16 @@
assertEquivalence(q.where(cb.literal(Boolean.FALSE)), FALSE_JPQL);
}
+ public void testBooleanLiteralInEquals() {
+ CriteriaQuery<Order> q = cb.createQuery(Order.class);
+ Root<Order> root = q.from(Order.class);
+ Path<Object> path = root.get("delivered");
+ Expression<Boolean> literal = cb.literal(Boolean.FALSE);
+ assertEquals( // we don't want o.delivered = 1 <> 1 but o.delivered = false
+ "SELECT o FROM Order o WHERE o.delivered = false",
+ ((OpenJPACriteriaQuery<?>) q.select(root).where(cb.equal(path, literal))).toCQL());
+ }
+
public void testDefaultAndIsTrue() {
CriteriaQuery<Person> q = cb.createQuery(Person.class);
q.from(Person.class);
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
index 05a6b13..a3e54ed 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
@@ -264,19 +264,19 @@
@Override
public <N extends Number> Expression<N> diff(Expression<? extends N> x,
Expression<? extends N> y) {
- return new Expressions.Diff<>(x, y);
+ return new Expressions.Diff<>(replaceExpressionForBinaryOperator(x), replaceExpressionForBinaryOperator(y));
}
@Override
public <N extends Number> Expression<N> diff(
Expression<? extends N> x, N y) {
- return new Expressions.Diff<>(x, y);
+ return new Expressions.Diff<>(replaceExpressionForBinaryOperator(x), y);
}
@Override
public <N extends Number> Expression<N> diff(N x,
Expression<? extends N> y) {
- return new Expressions.Diff<>(x, y);
+ return new Expressions.Diff<>(x, replaceExpressionForBinaryOperator(y));
}
@Override
@@ -288,7 +288,17 @@
public Predicate equal(Expression<?> x, Expression<?> y) {
if (y == null)
return new Expressions.IsNull((ExpressionImpl<?> )x);
- return new Expressions.Equal(x, y);
+ return new Expressions.Equal(replaceExpressionForBinaryOperator(x), replaceExpressionForBinaryOperator(y));
+ }
+
+ private <T> Expression<T> replaceExpressionForBinaryOperator(final Expression<T> expression) {
+ if (expression == PredicateImpl.TRUE()) {
+ return (Expression<T>) PredicateImpl.TRUE_CONSTANT;
+ }
+ if (expression == PredicateImpl.FALSE()) {
+ return (Expression<T>) PredicateImpl.FALSE_CONSTANT;
+ }
+ return expression;
}
@Override
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 9c6f34a..ea79d75 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
@@ -45,6 +45,9 @@
* @since 2.0.0
*/
abstract class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
+ static final Expression<?> TRUE_CONSTANT = new Expressions.Constant<>(true);
+ static final Expression<?> FALSE_CONSTANT = new Expressions.Constant<>(false);
+
private static Predicate TRUE;
private static Predicate FALSE;