Specifications
Dynamic search from small conditions
Imagine a search screen where the user can independently specify status, name, minimum age, and other filters. Creating a separate repository method for every combination quickly becomes inconvenient. For such cases, Spring Data JPA provides a Specification — an object that describes one query condition.
interface CustomerRepository
extends JpaRepository<Customer, Long>,
JpaSpecificationExecutor<Customer> {
}
Specification<Customer> active =
(root, query, cb) -> cb.isTrue(root.get("active"));
Specification<Customer> adult =
(root, query, cb) -> cb.greaterThanOrEqualTo(root.get("age"), 18);
List<Customer> customers = repository.findAll(active.and(adult));
Each specification describes a small predicate.
The JpaSpecificationExecutor interface adds methods that can execute such conditions,
and specifications can be combined with and, or, and negation.
When Specifications are especially useful
They work well for filters whose set is determined at runtime: for example, some fields in a search form may be filled in while others are empty. The code can add only the required conditions and then pass the resulting combination to the repository.
@Query is usually easier to read.