[英]Criteria JPA 2 join many to many unidirectional realtion
我有两个实体,电影和流派,从流派到电影具有多对多关系。 流派是关系的“父母”。
这会生成三个表: genre
、 movie
和genre_movie
@Entity
public class Genre {
@Id
@GeneratedValue(strategy = AUTO)
private Long id;
@ManyToMany(fetch = LAZY)
@JoinTable( name = "genre_movie",
joinColumns = {@JoinColumn(name = "genre_id")},
inverseJoinColumns = {@JoinColumn(name = "movie_id")}
)
private Set<Movie> movies = new HashSet<>();
...
}
@Entity
public class Movie {
@Id
@GeneratedValue(strategy = AUTO)
private Long id;
...
}
我可以使用条件查询 api 执行此查询吗? 根据流派 ID 过滤电影。
select *
from movie
join genre_movie on movie.id = genre_movie.movie_id
where genre_id = 19;
在电影方面双重映射您的 MovieGenre:
@ManyToMany(fetch = LAZY, mappedBy = "movies")
private Set<Genre> genres = new HashSet<>();
这不会创建额外的表,但(只是)使关联在“电影端”上可用(对于 JPA);;)
..然后我们可以查询(像往常一样,未经测试):
-- e.g. JPQL:
select [distinct] movie
from Movie movie
join movie.genres genre
where genre.id = :pGenreId
..传入Genre
ID。 或者:
select [distinct] movie
from Movie movie
where :pGenre member of movie.genres
...通过Genre
object(参数)。
也可以看看:
这是不可能的,因为 Movie 实体没有对 Genre 的引用,因为它不是双向的。
但是您可以重组查询以获得相同的结果:
Select * from genre
inner join genre_movie on genre.id = genre_movie.genre_id
inner join movie on genre_movie.movie_id = movie.id
where genre.genre_id = 19;
查询将按如下方式实现:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Movie> cq = cb.createQuery(Movie.class);
Root<Genre> rootGenre = cq.from(Genre.class);
Join<Genre,Movie> joinMovie = rootGenre.join("movies");
//Join<Genre,Movie> joinMovie = rootGenre.join(Genre_.movies);
cq.select(joinMovie);
cq.where(cb.equals(rootGenre.get("id"), 19));
//cq.where(cb.equals(rootGenre.get(Genre_.id), 19));
return this.em.createQuery(cq).getResultList();
我特别推荐使用元模型(注释行),因为在按字符串格式的名称访问属性时,可能会出现错误,而元模型不在更复杂的查询中。
我还认为将关系定义为双向以便能够将电影 class 设置为 Root 会很有趣
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.