2017-05-28 7 views
0

ich ein ähnliches Problem mit diesem haben: Spring Data Jpa and Specification - how to work with ManyToOne and ManyToMany relations?Spring Data JPA und Spezifikation - ManyToMany

Ich habe 3 Tabellen: Schauspieler, Film und mactors (die Tabelle für Filme und Schauspieler kommen) mit Federverschluß, 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; 
.... 

}

Ich mag würde diese Filme bekommen, wo zwei oder mehr Akteure zusammen gewesen sein. So etwas wie diese Abfrage:

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 ... 
    }; 
} 

Ich habe keine Ahnung, was als nächstes.

Jeder Hinweis würde geschätzt werden. Danke

Antwort

0

Es scheint, dass meine ursprüngliche SQL-Abfrage falsch war. Ein Arbeits SQL wäre:

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; 

Der Code unten funktioniert:

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; 
     } 
    }; 
} 

Ich schaffe es nicht in Klausel zu arbeiten, aber ich habe eine ODER in einer Schleife ...

Alle Tipps zur Verbesserung sind willkommen :)