java - JPA - 如何在查询多对多关系时防止不必要的连接

标签 java hibernate jpa pagination spring-data

<分区>

我有实体 Product 和 Category,它们通过简单的多对多关系连接在一起。我想获得按单个类别过滤的分页产品列表。我正在尝试编写一个 Spring Data JPA 自动方法或一个 JPQL 查询方法来生成类似于以下内容的 SQL:

select [...] FROM ProductToCategory ptc INNER JOIN Product p ON ptc.product_id=p.id WHERE ptc.category_id=?  LIMIT ? OFFSET ?

由于 ProductToCategory 连接表不是 JPA 实体 并且我无法在 JPQL 中引用它,所以我能做的最接近的事情想出是:

@Query("SELECT p FROM Category c INNER JOIN c.products p WHERE c=:category")
Page<Product> findByCategories(@Param("category") Category category, Pageable pageable);

但是生成的 SQL 产生了与 Category 表的冗余连接,并在那里应用了 where 子句,而不是 ProductToCategory 中的类别 id > 表。有没有一种方法可以在不求助于 native SQL 的情况下执行此操作?

最佳答案

我能看到的唯一方法是将一个实体映射到连接表,并将多对多 Product<>Category 替换为从 Product 和 Category 指向这个新实体的一对多关系。

这样的改变实际上符合 Hibernate 的最佳实践:

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/best-practices.html

Do not use exotic association mappings: Practical test cases for real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, most associations are one-to-many and many-to-one. For this reason, you should proceed cautiously when using any other association style.

关于java - JPA - 如何在查询多对多关系时防止不必要的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30769935/

相关文章:

java - 在 web.xml 中添加条件

java - Java API 设计中的面向对象事件日志记录

java - @OneToOne注解问题(我觉得。。。)

java - 使用 JPA 和 Hibernate 在 Persistence.xml 中配置 C3P0

java - 唯一索引或主键冲突

java - 检查文件夹是否存在,如果存在则添加 "New Folder 2"

java - 方法必须调用 Netbeans 中的 super() 错误

java - WeakHashMap 还是 HashMap?

java - JMS 与 Hibernate session

java - JPA Hibernate 保存 ManyToOne 字段为空