多对多实体上的 JPA WHERE 子句

Posted

技术标签:

【中文标题】多对多实体上的 JPA WHERE 子句【英文标题】:JPA WHERE clause on many-to-many entity 【发布时间】:2020-12-03 19:11:11 【问题描述】:

我有两个表,书和流派。每本书可能有多个流派,多对多表只包含书籍 ID 和流派 ID。 我想创建一个过滤器来按类型过滤书籍。

  @JoinTable(name = "bookGenre", joinColumns = 
    @JoinColumn(name = "bookId", referencedColumnName = "id"), inverseJoinColumns = 
    @JoinColumn(name = "genreId", referencedColumnName = "id"))
  @ManyToMany
  private Collection<Genre> genreCollection;

体裁类:

  @Id
  @Basic(optional = false)
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Integer id;
  @Size(max = 255)
  @Column(name = "name")
  private String name;
  @Column(name = "status")
  private Integer status;
  @ManyToMany(mappedBy = "genreCollection")
  private Collection<Book> bookCollection;

这是我尝试在 JPA 上执行的查询:

SELECT b.title FROM book b
JOIN bookGenre bg on bg.bookId = b.id
JOIN genre g on bg.genreId = g.id
WHERE g.id = 1
--Filter books that have genre with id 1

我在 JPA 上尝试了以下方法: SELECT b FROM Book b WHERE b.genreCollection.id = 1

但它给了我以下错误: “状态字段路径 'b.genreCollection.id' 无法解析为有效类型。”

编辑: 我发现我可以使用带有内置结果集映射到 Book POJO EntityManager.createNativeQuery(query, Book.class) 的本机 sql 查询。所以我只是使用它并将我的查询与 StringJoiner 串在一起。

【问题讨论】:

这能回答你的问题吗? How to properly express JPQL "join fetch" with "where" clause as JPA 2 CriteriaQuery? 我尝试使用 INNER JOIN,是的,它有效,但现在书籍列表正在重复。就像从明细表或我的案例 bookGenre 表中选择一样。 【参考方案1】:

我认为您的 JPA 查询应该是

SELECT b FROM Book b INNER JOIN b.genreCollection g WHERE g.id = 1

【讨论】:

它可以工作,但现在书籍列表正在重复,就像从明细表中选择一样 检查生成的SQL查询,是否正确生成?

以上是关于多对多实体上的 JPA WHERE 子句的主要内容,如果未能解决你的问题,请参考以下文章

多对多关系 JPA 与实体

JPA多对多映射

如何在多对多关系上使用休眠和 JPA 删除孤立实体?

JPA - 一个实体如何引用多对多关系中涉及的两个其他实体?

具有额外多对多关系的 JPA 多对多

JPA - 多对多集合的分页查询返回错误数量的实体