HHH-5736 Fixed problem with "not" function of CriteriaBuilder
This commit is contained in:
parent
e5da3bf149
commit
0c05f66f8d
|
@ -251,7 +251,10 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
// predicates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
public Predicate wrap(Expression<Boolean> expression) {
|
||||
if ( Predicate.class.isInstance( expression ) ) {
|
||||
if ( CompoundPredicate.class.isInstance( expression ) ) {
|
||||
return (( CompoundPredicate ) expression);
|
||||
}
|
||||
else if(Predicate.class.isInstance(expression)) {
|
||||
return ( ( Predicate ) expression );
|
||||
}
|
||||
else if ( PathImplementor.class.isInstance( expression ) ) {
|
||||
|
|
|
@ -44,7 +44,7 @@ import org.hibernate.ejb.criteria.Renderable;
|
|||
public class CompoundPredicate
|
||||
extends AbstractPredicateImpl
|
||||
implements Serializable {
|
||||
private final BooleanOperator operator;
|
||||
private BooleanOperator operator;
|
||||
private final List<Expression<Boolean>> expressions = new ArrayList<Expression<Boolean>>();
|
||||
|
||||
/**
|
||||
|
@ -148,4 +148,29 @@ public class CompoundPredicate
|
|||
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
return render( renderingContext );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create negation of compound predicate by using logic rules:
|
||||
* 1. not (x || y) is (not x && not y)
|
||||
* 2. not (x && y) is (not x || not y)
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Predicate not() {
|
||||
if (this.operator == BooleanOperator.AND) {
|
||||
this.operator = BooleanOperator.OR;
|
||||
} else {
|
||||
this.operator = BooleanOperator.AND;
|
||||
}
|
||||
for (Expression expr : this.getExpressions()) {
|
||||
if (Predicate.class.isInstance(expr)) {
|
||||
( (Predicate) expr ).not();
|
||||
}
|
||||
else if(CompoundPredicate.class.isInstance(expr)) {
|
||||
( (CompoundPredicate) expr ).not();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
|
||||
import org.hibernate.ejb.metamodel.AbstractMetamodelSpecificTest;
|
||||
import org.hibernate.ejb.metamodel.Order;
|
||||
|
@ -64,4 +65,70 @@ public class PredicateTest extends AbstractMetamodelSpecificTest {
|
|||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check simple not.
|
||||
*/
|
||||
public void testSimpleNot() {
|
||||
// yes this is a retarded case, but explicitly allowed in the JPA spec
|
||||
CriteriaBuilder builder = factory.getCriteriaBuilder();
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
CriteriaQuery<Order> orderCriteria = builder.createQuery(Order.class);
|
||||
Root<Order> orderRoot = orderCriteria.from(Order.class);
|
||||
|
||||
orderCriteria.select(orderRoot);
|
||||
orderCriteria.where( builder.not( builder.equal(orderRoot.get("id"), 1) ) );
|
||||
|
||||
em.createQuery( orderCriteria ).getResultList();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check complicated not.
|
||||
*/
|
||||
public void testComplicatedNotOr() {
|
||||
// yes this is a retarded case, but explicitly allowed in the JPA spec
|
||||
CriteriaBuilder builder = factory.getCriteriaBuilder();
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
CriteriaQuery<Order> orderCriteria = builder.createQuery(Order.class);
|
||||
Root<Order> orderRoot = orderCriteria.from(Order.class);
|
||||
|
||||
orderCriteria.select(orderRoot);
|
||||
Predicate p1 = builder.equal(orderRoot.get("id"), 1);
|
||||
Predicate p1 = builder.equal(orderRoot.get("id"), 2);
|
||||
orderCriteria.where( builder.not( builder.or (p1, p2) ) );
|
||||
|
||||
em.createQuery( orderCriteria ).getResultList();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check complicated not.
|
||||
*/
|
||||
public void testComplicatedNotAND() {
|
||||
// yes this is a retarded case, but explicitly allowed in the JPA spec
|
||||
CriteriaBuilder builder = factory.getCriteriaBuilder();
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
CriteriaQuery<Order> orderCriteria = builder.createQuery(Order.class);
|
||||
Root<Order> orderRoot = orderCriteria.from(Order.class);
|
||||
|
||||
orderCriteria.select(orderRoot);
|
||||
Predicate p1 = builder.equal(orderRoot.get("id"), 1);
|
||||
Predicate p1 = builder.equal(orderRoot.get("id"), 2);
|
||||
orderCriteria.where( builder.not( builder.and (p1, p2) ) );
|
||||
|
||||
em.createQuery( orderCriteria ).getResultList();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue