繁体   English   中英

在 JPA + Hibernate 中使用单向@ManyToOne 关系时,有没有办法避免 N+1 查询?

[英]Is there a way to avoid N+1 queries when using a unidirectional @ManyToOne relationship in JPA + Hibernate?

我有以下实体:

假人A:

@Entity
@Table(name = "dummy_a")
@Data
public class DummyA implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;


@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "dummy_b_name", referencedColumnName = "name", updatable = false, insertable = false)
private DummyB dummyB;
}

哑巴B:

@Entity
@Table(name = "dummy_b")
@Data
public class DummyB implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "entity_id")
private Integer id;

@Column(name = "name")
private String name;
}

按照目前的情况,任何获取DummyA对象的尝试都会导致额外的查询以获取DummyB对象。 由于 N+1 查询,这会导致不可接受的额外延迟,并且还会破坏repository.findAll(specification, pageable)返回的Page对象,导致返回不正确的总页数和元素数(在我的例子中repository extends JpaRepository )。 有没有一种方法可以延迟加载 DummyB 对象,或者如果不可能,则可以在单个查询中急切加载它们?

限制:我是 JPA 和 Hibernate 的新手,一直在学习如何使用它们。 我在我正在从事的项目中遇到了以下问题。 我没有自由包含新的依赖项,我的项目目前不允许通过@LazyToOne(LazyToOneOption.NO_PROXY)增强 hibernate 字节码。

到目前为止我已经尝试过但没有工作/没有按预期工作的事情:

  1. @ManyToOne(optinoal = false, fetch = FetchType.LAZY)
  2. 试图通过删除dummyB的 setter 和 getter 来查看访问 dummyA 中的dummyB字段dummyA是导致 N+1 查询的原因。 仍然有 N+1 个查询。
  3. findAll上使用@EntityGraph
  4. 尝试实施PersistentAttributeInterceptable并使用PersistentAttributeInterceptor来解决问题。

到目前为止我查找的资源链接:

  1. @ManyToOne(fetch = FetchType.LAZY) 不适用于非主键引用列
  2. JPA和Hibernate的N+1查询问题
  3. Hibernate 反向一对一解决方法的延迟加载 - 这是如何工作的?
  4. PersistentAttributeInterceptable
  5. JPA实体图

任何帮助是极大的赞赏。

如果有人好奇,我会回来回答。 事实证明,某些条目在DummyA用作外键以将其与DummyB关联的列中具有无效的“魔术”值,导致 Hibernate 对这些 null 值执行单独的查询,以检查是否确实找不到关联(请参阅此文档相关问题的答案)。 我将这些查询误认为是 N+1。 该项目还有一个拦截器,它扩展了 Hibernate 的EmptyInterceptor ,以便修改生成页面的查询,如果执行辅助查询,则会导致错误的计数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM