Spring Boot here. I'm trying to wrap my head around JpaRepositories
and Specifications
when used in the context of implementing complex queries and am struggling to see the "forest through the trees" on several items.
A canonical example of a Specification
is as follows:
public class PersonSpecification implements Specification<Person> {
private Person filter;
public PersonSpecification(Person filter) {
super();
this.filter = filter;
}
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq,
CriteriaBuilder cb) {
Predicate p = cb.disjunction();
if (filter.getName() != null) {
p.getExpressions()
.add(cb.equal(root.get("name"), filter.getName()));
}
if (filter.getSurname() != null && filter.getAge() != null) {
p.getExpressions().add(
cb.and(cb.equal(root.get("surname"), filter.getSurname()),
cb.equal(root.get("age"), filter.getAge())));
}
return p;
}
}
In this toPredicate(...)
method, what do the Root<Person>
and CriteriaQuery
represent? Most importantly, it sounds like you need to create one Specification
impl for each type of filter you want to apply, because each spec gets translated into one and only one predicate...so for instance if I wanted to find all people with a surname of "Smeeb" and an age greater than 25, it sounds like I would need to write a LastnameMatchingSpecification<Person>
as well as a AgeGreaterThanSpecification<Person>
. Can someone confirm or clarify this for me?!