I have a rather big system with a specification that is built by several methods on a child entity. So I have a User with a OneToMany on pets, as in this question . My relation is bidirectional, so Pet also has a ManyToOne relationship on User, and I'm struggling in transforming the specification on child entity to apply on parent entity instead.
Most questions I looked up showed how to apply a specification on a different entity, OR to get a different entity once the specification was executed. This is NOT what i'm looking for.
I'm trying to write a method like this :
public static Specification<User> extendsPetSpecToUser(
Specification<Pet> petSpec) {
// ???
}
but I don't know how to write it (I tried using Join, but didn't manage to "say" to JPA to combine the join and the specification to query with a different root but similar constraints)
Given the specification is big AND also used in other parts to query directly for Pet, rewriting it from a different root isn't really an option.
Thank you for your time, and sorry if this is a duplicate, I really didn't see another question matching my needs.
First, it feels like this problem hides a weird construction of the queries you use.
Why would you build a Specification<Pet>
if you need Specification<User>
at the end ?
There might be a code architecture to think about.
Anyway, to achieve the mentioned goal, have you tried using subqueries ?
public class TransformToUser implements Specification<User> {
private final Specification<Pet> specification;
public TransformToUser (Specification<Pet> specification) {
this.specification = specification;
}
@Override
public Predicate toPredicate(
Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Subquery<Pet> subqueryPet = criteriaQuery.subquery(Pet.class);
Root<Pet> fromPet = subqueryDeclaration.from(Pet.class);
subqueryPet.select(fromPet);
subqueryPet.where(
specification.toPredicate(fromPet, criteriaQuery, criteriaBuilder));
return root.get(User_.pets).in(subqueryPet);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.