HHH-8480 - JPA Predicate#not() on a simple predicate should leave the operator as AND, not mutate it to OR

This commit is contained in:
Steve Ebersole 2013-09-10 17:16:11 -05:00
parent cbd828217a
commit a3f1c247bc
2 changed files with 39 additions and 5 deletions

View File

@ -48,7 +48,9 @@ public class NegatedPredicateWrapper extends ExpressionImpl<Boolean> 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() );
}

View File

@ -111,7 +111,30 @@ public void testSimpleNot() {
Root<Order> 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<Order> 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<Order> orderCriteria = builder.createQuery( Order.class );
Root<Order> 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<Order> 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<Order> 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<Order> 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<Order> orders = em.createQuery( orderCriteria ).getResultList();
assertEquals( 3, orders.size() );