I have a similar problem with this one: Spring Data Jpa and Specification - how to work with ManyToOne and ManyToMany relations?
I have 3 tables: actor, movie and mactors (the join table for movies and actors) with spring boot, hibernate-jpamodelgen
@Entity
public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
...
}
@Entity
public class Movie implements BaseId {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
....
}
I would like to get those movies where 2 or more actors have been in together. Something like this query:
select * from movie
join mactors on movie.id = mactors.movie
where mactors.actor = x and mactors.actor = y and ...;
public static Specification<Movie> findMoviesByActors(List<Long> actors) {
return (root, criteriaQuery, criteriaBuilder) -> {
...
return ...
};
}
I have no clue what next.
Any hint would be appreciated. Thanks
It seems that my original SQL query was wrong. An working SQL would be:
select distinct * from movie
join mactors on movie.id = mactors.movie_id
where mactors.actor_id in (x, y, z...)
group by movie.title
having count(movie.id) >= numberOfActors;
The code bellow works:
public static Specification<Movie> findByActorsId(List<Long> actorIds) {
return new Specification<Movie>() {
@Override
public Predicate toPredicate(Root<Movie> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Join<Movie, Actor> join = root.join(Movie_.actors);
Predicate actorIdPredicate = cb.disjunction();
for(Long aid : actorIds) {
actorIdPredicate.getExpressions().add(cb.equal(join.get(Actor_.id), aid));
}
Expression<Long> count = cb.count(root.get(Movie_.id));
CriteriaQuery<Movie> q = (CriteriaQuery<Movie>) query.distinct(true).groupBy(root.get(Movie_.title)).
having(cb.greaterThanOrEqualTo(count, new Long(actorIds.size()));
return actorIdPredicate;
}
};
}
I didn't manage to get in clause to work, but I did an OR in a loop...
Any tips to improve are welcome :)
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.