From a3f1c247bcf81b1383d5112a601d730be90c0572 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 10 Sep 2013 17:16:11 -0500 Subject: [PATCH] HHH-8480 - JPA Predicate#not() on a simple predicate should leave the operator as AND, not mutate it to OR --- .../predicate/NegatedPredicateWrapper.java | 4 +- .../test/criteria/basic/PredicateTest.java | 40 +++++++++++++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/NegatedPredicateWrapper.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/NegatedPredicateWrapper.java index a6ed283550..aca2fa5cd1 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/NegatedPredicateWrapper.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/NegatedPredicateWrapper.java @@ -48,7 +48,9 @@ public class NegatedPredicateWrapper extends ExpressionImpl implements public NegatedPredicateWrapper(PredicateImplementor predicate) { super( predicate.criteriaBuilder(), Boolean.class ); this.predicate = predicate; - this.negatedOperator = CompoundPredicate.reverseOperator( predicate.getOperator() ); + this.negatedOperator = predicate.isJunction() + ? CompoundPredicate.reverseOperator( predicate.getOperator() ) + : predicate.getOperator(); this.negatedExpressions = negateCompoundExpressions( predicate.getExpressions(), predicate.criteriaBuilder() ); } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java index 86ba8435db..3a70c8665a 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java @@ -111,7 +111,30 @@ public void testSimpleNot() { Root orderRoot = orderCriteria.from( Order.class ); orderCriteria.select( orderRoot ); - orderCriteria.where( builder.not( builder.equal( orderRoot.get( "id" ), "order-1" ) ) ); + final Predicate p = builder.not( builder.equal( orderRoot.get( "id" ), "order-1" ) ); + assertEquals( Predicate.BooleanOperator.AND, p.getOperator() ); + orderCriteria.where( p ); + + List orders = em.createQuery( orderCriteria ).getResultList(); + assertEquals( 2, orders.size() ); + em.getTransaction().commit(); + em.close(); + } + + /** + * Check simple not. + */ + @Test + public void testSimpleNot2() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + CriteriaQuery orderCriteria = builder.createQuery( Order.class ); + Root orderRoot = orderCriteria.from( Order.class ); + + orderCriteria.select( orderRoot ); + final Predicate p = builder.equal( orderRoot.get( "id" ), "order-1" ).not(); + assertEquals( Predicate.BooleanOperator.AND, p.getOperator() ); + orderCriteria.where( p ); List orders = em.createQuery( orderCriteria ).getResultList(); assertEquals( 2, orders.size() ); @@ -132,7 +155,10 @@ public void testComplicatedNotOr() { orderCriteria.select( orderRoot ); Predicate p1 = builder.equal( orderRoot.get( "id" ), "order-1" ); Predicate p2 = builder.equal( orderRoot.get( "id" ), "order-2" ); - orderCriteria.where( builder.not( builder.or( p1, p2 ) ) ); + Predicate compoundPredicate = builder.not( builder.or( p1, p2 ) ); + // negated OR should become an AND + assertEquals( Predicate.BooleanOperator.AND, compoundPredicate.getOperator() ); + orderCriteria.where( compoundPredicate ); List orders = em.createQuery( orderCriteria ).getResultList(); assertEquals( 1, orders.size() ); @@ -156,7 +182,10 @@ public void testNotMultipleOr() { Predicate p1 = builder.equal( orderRoot.get( "id" ), "order-1" ); Predicate p2 = builder.equal( orderRoot.get( "id" ), "order-2" ); Predicate p3 = builder.equal( orderRoot.get( "id" ), "order-3" ); - orderCriteria.where( builder.not( builder.or( p1, p2, p3 ) ) ); + final Predicate compoundPredicate = builder.or( p1, p2, p3 ).not(); + // negated OR should become an AND + assertEquals( Predicate.BooleanOperator.AND, compoundPredicate.getOperator() ); + orderCriteria.where( compoundPredicate ); List orders = em.createQuery( orderCriteria ).getResultList(); assertEquals( 0, orders.size() ); @@ -177,7 +206,10 @@ public void testComplicatedNotAnd() { orderCriteria.select( orderRoot ); Predicate p1 = builder.equal( orderRoot.get( "id" ), "order-1" ); Predicate p2 = builder.equal( orderRoot.get( "id" ), "order-2" ); - orderCriteria.where( builder.not( builder.and( p1, p2 ) ) ); + Predicate compoundPredicate = builder.and( p1, p2 ).not(); + // a negated AND should become an OR + assertEquals( Predicate.BooleanOperator.OR, compoundPredicate.getOperator() ); + orderCriteria.where( compoundPredicate ); List orders = em.createQuery( orderCriteria ).getResultList(); assertEquals( 3, orders.size() );