Skip to content

Commit a3f1c24

Browse files
committed
HHH-8480 - JPA Predicate#not() on a simple predicate should leave the operator as AND, not mutate it to OR
1 parent cbd8282 commit a3f1c24

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/NegatedPredicateWrapper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ public class NegatedPredicateWrapper extends ExpressionImpl<Boolean> implements
4848
public NegatedPredicateWrapper(PredicateImplementor predicate) {
4949
super( predicate.criteriaBuilder(), Boolean.class );
5050
this.predicate = predicate;
51-
this.negatedOperator = CompoundPredicate.reverseOperator( predicate.getOperator() );
51+
this.negatedOperator = predicate.isJunction()
52+
? CompoundPredicate.reverseOperator( predicate.getOperator() )
53+
: predicate.getOperator();
5254
this.negatedExpressions = negateCompoundExpressions( predicate.getExpressions(), predicate.criteriaBuilder() );
5355
}
5456

hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,30 @@ public void testSimpleNot() {
111111
Root<Order> orderRoot = orderCriteria.from( Order.class );
112112

113113
orderCriteria.select( orderRoot );
114-
orderCriteria.where( builder.not( builder.equal( orderRoot.get( "id" ), "order-1" ) ) );
114+
final Predicate p = builder.not( builder.equal( orderRoot.get( "id" ), "order-1" ) );
115+
assertEquals( Predicate.BooleanOperator.AND, p.getOperator() );
116+
orderCriteria.where( p );
117+
118+
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
119+
assertEquals( 2, orders.size() );
120+
em.getTransaction().commit();
121+
em.close();
122+
}
123+
124+
/**
125+
* Check simple not.
126+
*/
127+
@Test
128+
public void testSimpleNot2() {
129+
EntityManager em = getOrCreateEntityManager();
130+
em.getTransaction().begin();
131+
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
132+
Root<Order> orderRoot = orderCriteria.from( Order.class );
133+
134+
orderCriteria.select( orderRoot );
135+
final Predicate p = builder.equal( orderRoot.get( "id" ), "order-1" ).not();
136+
assertEquals( Predicate.BooleanOperator.AND, p.getOperator() );
137+
orderCriteria.where( p );
115138

116139
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
117140
assertEquals( 2, orders.size() );
@@ -132,7 +155,10 @@ public void testComplicatedNotOr() {
132155
orderCriteria.select( orderRoot );
133156
Predicate p1 = builder.equal( orderRoot.get( "id" ), "order-1" );
134157
Predicate p2 = builder.equal( orderRoot.get( "id" ), "order-2" );
135-
orderCriteria.where( builder.not( builder.or( p1, p2 ) ) );
158+
Predicate compoundPredicate = builder.not( builder.or( p1, p2 ) );
159+
// negated OR should become an AND
160+
assertEquals( Predicate.BooleanOperator.AND, compoundPredicate.getOperator() );
161+
orderCriteria.where( compoundPredicate );
136162

137163
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
138164
assertEquals( 1, orders.size() );
@@ -156,7 +182,10 @@ public void testNotMultipleOr() {
156182
Predicate p1 = builder.equal( orderRoot.get( "id" ), "order-1" );
157183
Predicate p2 = builder.equal( orderRoot.get( "id" ), "order-2" );
158184
Predicate p3 = builder.equal( orderRoot.get( "id" ), "order-3" );
159-
orderCriteria.where( builder.not( builder.or( p1, p2, p3 ) ) );
185+
final Predicate compoundPredicate = builder.or( p1, p2, p3 ).not();
186+
// negated OR should become an AND
187+
assertEquals( Predicate.BooleanOperator.AND, compoundPredicate.getOperator() );
188+
orderCriteria.where( compoundPredicate );
160189

161190
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
162191
assertEquals( 0, orders.size() );
@@ -177,7 +206,10 @@ public void testComplicatedNotAnd() {
177206
orderCriteria.select( orderRoot );
178207
Predicate p1 = builder.equal( orderRoot.get( "id" ), "order-1" );
179208
Predicate p2 = builder.equal( orderRoot.get( "id" ), "order-2" );
180-
orderCriteria.where( builder.not( builder.and( p1, p2 ) ) );
209+
Predicate compoundPredicate = builder.and( p1, p2 ).not();
210+
// a negated AND should become an OR
211+
assertEquals( Predicate.BooleanOperator.OR, compoundPredicate.getOperator() );
212+
orderCriteria.where( compoundPredicate );
181213

182214
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
183215
assertEquals( 3, orders.size() );

0 commit comments

Comments
 (0)