2017-05-31 94 views
0

我在獲取數據時遇到了一些問題。Hibernate ManyToMany IN子句

我的實體:

@MappedSuperclass 
public abstract class BaseJpa { 

    @Id 
    private Integer id; 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 
} 

@Entity 
@Table(name="genres") 
public class GenreJpa extends BaseJpa{ 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

@Entity 
@Table(name="movies") 
public class MovieJpa extends BaseJpa{ 

    @Type(type="text") 
    private String name; 

    private String releaseDate; 

    @Type(type="text") 
    private String summary; 

    @ManyToMany(cascade={CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.LAZY) 
    private List<GenreJpa> genres; 

    private long votes; 

    private double rank; 

    public long getVotes() { 
     return votes; 
    } 

    public void setVotes(long votes) { 
     this.votes = votes; 
    } 

    public double getRank() { 
     return rank; 
    } 

    public void setRank(double rank) { 
     this.rank = rank; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getReleaseDate() { 
     return releaseDate; 
    } 

    public void setReleaseDate(String releaseDate) { 
     this.releaseDate = releaseDate; 
    } 

    public String getSummary() { 
     return summary; 
    } 

    public void setSummary(String summary) { 
     this.summary = summary; 
    } 

    public List<GenreJpa> getGenres() { 
     return genres; 
    } 

    public void setGenres(List<GenreJpa> genres) { 
     this.genres = genres; 
    } 

} 

基於這些實體,我有表數據:

genres 
---------------- 
id | name 
---------------- 
0 | Documentary 
1 | Comedy 
2 | Drama 

movies 
--------------------------------------------------- 
id | name | rank | releasedate | summary | votes 
--------------------------------------------------- 
15 | Movie 1 | 4.5 | 1990  |   | 605 
16 | Movie 2 | 4.5 | 2005  |   | 709 

movies_genres 
----------------------------------------------- 
moviejpa_id (movies.id) | genres_id (genres.id) 
----------------------------------------------- 
15      | 1 
15      | 2 
16      | 0 

比方說,我需要檢索影片,其中有流派喜劇和戲劇。我試圖用in()來做到這一點,但到目前爲止我失敗了。任何人都可以提供一些建議如何解決這個問題?或者我應該只使用本地SQL,並忘記動態和標準?

EntityManager entityManager = EMF.get().createEntityManager(); 
MovieJpa movieJpa = null; 
try{ 
    CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 
    CriteriaQuery<MovieJpa> criteria = builder.createQuery(MovieJpa.class); 
    Root<MovieJpa> root = criteria.from(MovieJpa.class); 
    Root<GenreJpa> sub = criteria.from(GenreJpa.class); 
    criteria.select(root); 

    //root.get(MovieJpa_.genres).in(filter.getGenres()); 
    //sub.get(GenreJpa_.name).in(filter.getGenres()) 

    criteria.where(new Predicate[]{root.get(MovieJpa_.genres).in(filter.getGenres()), 
            builder.between(root.get(MovieJpa_.rank), filter.getMinRank(), filter.getRank()), 
            builder.between(root.get(MovieJpa_.votes), filter.getMinVotes(), filter.getVotes())}); 
    movieJpa = entityManager.createQuery(criteria).setMaxResults(1).getResultList().get(0); 

} catch (Exception e){ 
    e.printStackTrace(); 
} finally { 
    entityManager.close(); 
} 
return movieJpa; 

public class Filter { 

    private List<Genre> genres; 

    private String genre; 

    private String yearStart; 

    private String yearEnd; 

    private double rank; 

    private double minRank; 

    private double maxRank; 

    private long votes; 

    private long minVotes; 

    private long maxVotes; 
    --getters/setters 

回答

0

找到答案:JPA criteria query in a many-to-many relationship using IN operator

所有我不得不改變是改用不用彷徨的。加入。

 criteria.where(new Predicate[]{root.join(MovieJpa_.genres).in(genreJpaList), 
             builder.between(root.get(MovieJpa_.rank), filter.getMinRank(), filter.getRank()), 
             builder.between(root.get(MovieJpa_.votes), filter.getMinVotes(), filter.getVotes())}); 
     movieJpa = entityManager.createQuery(criteria).setMaxResults(1).getResultList().get(0);