簡體   English   中英

標准 JPA 2 加入多對多單向實體

[英]Criteria JPA 2 join many to many unidirectional realtion

我有兩個實體,電影和流派,從流派到電影具有多對多關系。 流派是關系的“父母”。
這會生成三個表: genremoviegenre_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM