I am using JPA Criteria API in a Spring data JPA based application. My service class uses static methods to retrieve Specifications
which can then be combined together to form a particular query. E.g.
repository.findAll(where(matchById(str)).or(matchByName(str)))
Here, I am using two methods that return Specifications with the appropriate criteria applied to it. This is how the two methods look like
public static Specification<SomeEntity> matchById(String str) {
return (root, criteriaQuery, cb) ->
cb.like(root.get(SomeEntity_.id).as(String.class), str + "%");
}
public static Specification<SomeEntity> matchByName(String str) {
return (root, criteriaQuery, cb) -> {
cb.or(cb.like(cb.lower(root.get(SomeEntity_.firstName)), str.toLowerCase() + "%"),
cb.like(cb.lower(root.get(SomeEntity_.lastName)), str.toLowerCase() + "%")
);
}
This works fine. I want to add a
root.fetch(SomeEntity_.employee, JoinType.INNER);
in such a way that all queries that are built using any combination of static Specifications methods, utilize the FETCH JOIN
.
If I add this statement to both static methods, then the INNER JOIN is applied twice which doesnt seem right. Ideally, I think I should have another static method that only applies the FETCH JOIN
and return the Specifications but I cant seem to figure out how to return a Predicate
without using any of the criteriaBuilder
methods. To clarify, this is how my method should look like:
public static Specification<SomeEntity> start() {
return (root, criteriaQuery, criteriaBuilder) -> {
root.fetch(SomeEntity_.employee, JoinType.INNER);
// NOW RETURN WHAT ???
return null;
};
}
Any help would be appreciated.