In my previous article I showed how to create composed specifications using the JPA 2.0 Criteria API. This article shows the source code of the Specification interface and the core components (including boolean operators).
We first start with the Specification interface:
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
/**
* <code>Specification</code> is used to test an object to see if it satisfies
* a certain criteria.
*
* @author had
* @author http://dddsample.sourceforge.net/
*
* @param The type of the object to test.
*/
public interface Specification {
/**
* Tests the specified <code>candidate</code> if it satisfies the criteria
* of this specification.
* @param candidate The object to test.
* @return <code>true</code> if <code>testObject</code> satisfies the
* criteria of this specification, <code>false</code> otherwise.
*/
boolean isSatisfiedBy(T candidate);
/**
* Transforms this specification into a predicate. (optional)
* @param cb The criteria builder to use, must not be null.
* @param query The query object to use, must not be null.
* @param root The starting point, must not be null.
* @return The created predicate which checks the rules.
* @throws UnsupportedOperationException If this specification does not
* support predicate transformation.
*/
Predicate toPredicate(CriteriaBuilder cb, CriteriaQuery query, Root root) throws UnsupportedOperationException;
Specification and(Specification other);
Specification or(Specification other);
Specification not();
}
Based on the ideas published by Eric Evans (author of the book “Domain Driven Design”), this interface contains the following methods:
- isSatisfiedBy – to check an in-memory object if it satisifies the specification
- and, or, not – for boolean operations on the specification
The interface above has an additional method called toPredicate. This method transforms the (business-driven) intention of the specification into a Predicate which is used to fetch all persisted objects satisfying the specification – one important aspect of the Specification concept. The Predicate interface is defined by the JPA 2.0 Criteria API and can be used to build dynamic queries using predicates (as shown in the previous article).
An abstract specification implements the Specification interface as follows:
public abstract class AbstractSpecification<T> implements Specification<T> {
@Override
public Specification<T> and(Specification<T> other) {
return new AndSpecification<T>(this, other);
}
@Override
public Specification<T> or(Specification<T> other) {
return new OrSpecification<T>(this, other);
}
@Override
public Specification<T> not() {
return new NotSpecification<T>(this);
}
}
Last but not least, we need common implementations for the boolean operators:
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
public class AndSpecification<T> extends AbstractSpecification<T> {
private final Specification<T> a;
private final Specification<T> b;
public AndSpecification(Specification<T> a, Specification<T> b) {
this.a = a;
this.b = b;
}
@Override
public boolean isSatisfiedBy(T candidate) {
return a.isSatisfiedBy(candidate) && b.isSatisfiedBy(candidate);
}
@Override
public Predicate toPredicate(CriteriaBuilder cb, CriteriaQuery<T> query, Root<T> root) throws UnsupportedOperationException {
return cb.and(a.toPredicate(cb, query, root), b.toPredicate(cb, query, root));
}
}
One can easily imagine, how the OrSpecification and the NotSpecification look like.

great addition !!
thank you,
Shay