【问题标题】:Hibernate ManyToMany IN clauseHibernate ManyToMany IN 子句
【发布时间】:2017-05-31 16:45:22
【问题描述】:

我在获取数据时遇到了一些问题。

我的实体:

@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

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

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

    我所要做的只是使用 .join 而不是 .get。

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

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 2019-04-01
      • 1970-01-01
      • 2014-09-10
      • 2021-05-15
      • 2015-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多