java - ManyToMany N+1 问题 - 所有右侧均未返回

标签 java spring hibernate jpa hql

我编写的代码存在 N+1 问题。 它是双向多对多关系。 我正在尝试使用 LEFT JOIN FETCH 解决它

我遇到的问题是,当我查看结果时,只有右侧的 1 个记录被加入。每个留下的记录应该还有更多。

左侧记录返回正确,但 Set 属性仅包含右侧的 1 个实例。

      value = "SELECT cat from CatEntity cat "
          + "INNER JOIN cat.owner o "
          + "LEFT JOIN FETCH cat.toys "
          + "WHERE (o.name = :something)

我得到了全部 69 只猫的记录,但是有玩具的猫只有 1 个玩具。 如果我删除 LEFT JOIN FETCH。我得到了所有的猫和所有完整的玩具......当然还有 N+1 问题。 当我添加 LEFT JOIN FETCH.. 它解决了 N+1 问题,但不返回完整的玩具套装。

public class CatEntity implements Serializable {
  @JoinTable(
      name = "cat_toy",
      joinColumns = {@JoinColumn(name = "cat_id")},
      inverseJoinColumns = {@JoinColumn(name = "toy_id")})
  @Fetch(FetchMode.JOIN)
  @OrderBy(value = "toy_index desc")
  private Set<ToyEntity> toys;
}
}

public class ToyEntity implements Serializable {

 @ManyToMany(mappedBy = "toys")
  Set<CatEntity> cats;
}

如何避免 N+1 问题但完全填充集合?

//公司不赞成发布代码,因此我使用 cat/toy 作为替换类名的示例。

最佳答案

我找到了解决问题的方法。我会在这里发帖希望对其他人有帮助。

我正在使用

@Fetch(FetchMode.JOIN)

在我的代码中。我需要使用

@Fetch(FetchMode.SUBSELECT)

这是专为 Collection 而设计的。它使用 2 个查询而不是 N+1 来填充 ManyToMany 双向关系的右侧。

它首先得到所有的猫。然后它得到所有的玩具。仅执行 2 个查询。

您不应将 LEFT JOIN FETCH 放入查询本身中。只需将获取模式添加到实体映射即可。

希望这对其他人有帮助。

关于java - ManyToMany N+1 问题 - 所有右侧均未返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70567098/

相关文章:

java - 使用 Solr 索引文档导致预期的 MIME 类型应用程序/八位字节流但得到 text/html

java - 单击按钮后向 JPanel 添加按钮

java - 如何在 Spring MVC Web 应用程序中从 Tomcat 自定义目录读取文件

java - Spring 启动 JPA : Could not Extract Result Set Error

java - 我们如何知道哪个登录用户正在使用java中的表单?

postgresql - 如何在 Hibernate 中映射 PostgreSQL Interval 列类型?

java - 尝试同时保存到两个数据库时,找不到当前线程的 session 错误

Java - 如何绘制虚线和波浪线?

java - 嵌入式 Jetty 和 Jax-rs xml 配置

java - SpringExtension 没有显式配置?