In the Spring Data JPA - Reference Documentation, a criteria is defined by:
Writing a criteria you actually define the where-clause of a query for a domain class.
Specifications and predicates seem to have the same role.
What is the difference between a criteria, a predicate and a specification?
The Iterable<T> findAll(Predicate predicate) returns objects that fulfil the conditions specified by the Predicate object given as a method parameter. The T findOne(Predicate predicate) method returns an object that fulfils the conditions specified by the Predicate object given as a method parameter.
The type of a simple or compound predicate: a conjunction or disjunction of restrictions. A simple predicate is considered to be a conjunction with a single conjunct.
The Criteria API is a predefined API used to define queries for entities. It is the alternative way of defining a JPQL query. These queries are type-safe, and portable and easy to modify by changing the syntax.
The Criteria API was added in JPA 2.0. According to the Java Persistence wikibook:
The Java Persistence Criteria API is used to define dynamic queries through the construction of object-based query definition objects, rather than use of the string-based approach of JPQL.
A CriteriaBuilder
is used to build a CriteriaQuery
objects which is then used to perform a query such as in this example from the Java persistence wikibook:
// Query for a List of objects.
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
Root employee = criteriaQuery.from(Employee.class);
criteriaQuery.where(criteriaBuilder.greaterThan(employee.get("salary"), 100000));
Query query = entityManager.createQuery(criteriaQuery);
List<Employee> result = query.getResultList();
The Predicate
class is part of the Criteria API and is used to construct where clauses. Such as in this modifed example taken from the Java EE 7 documentation:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
Predicate predicate1 = cb.equal(pet.get(Pet_.name), "Fido");
Predicate predicate2 = cb.equal(pet.get(Pet_.color), "brown");
cq.where(predicate1.and(predicate2));
The Specification
interface is defined by the Spring Data JPA project. According to the following blog post, Advanced Spring Data JPA - Specifications and Querydsl, from Oliver Gierke:
To be able to define reusable Predicates we introduced the Specification interface that is derived from concepts introduced in Eric Evans’ Domain Driven Desig book. A Specification can be defined such as:
public static Specification<Customer> customerHasBirthday() {
return new Specification<Customer> {
public Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb) {
return cb.equal(root.get(Customer_.birthday), today);
}
};
}
and then used in a JpaSpecificationExecutor
.
List<Customer> customers = customerRepository.findAll(customerHasBirthday());
NOT from API Docs but as I see it:
Criteria
is an abstract concept, kind a collection of Predicates
. CriteriaQuery
has all the Criteria
set as Predicate
s.
As Criteria
is a plural of Criterion
might say that Predicate
equals to Criterion
.
Spring Specification
is meant to be implemented to provide means to use specification pattern
when constructing CriteriaQueries
.
Feel free to correct me with - preferably API- documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With