首页 > 解决方案 > JPA Lazy with Entity Graph 发出额外的请求

问题描述

假设我有 2 个对象 A 和 B 一对一相关,B 嵌套在 A 下。B 是延迟初始化和代理的,而且我有一个实体图可以在加载 A 时急切地获取 B,如下所示。

@NamedEntityGraph(name = "subGraph",attributeNodes = {@NamedAttributeNode("sub")})
public class A{
    Integer id;
    String name;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id", insertable = false, updatable = false)
    B sub;
}


public class B {
    int id;
    String description;
}

让我们从数据库中查询一个 A 流,并尝试设置 DTO 对象并添加到 DTO 列表中:

1. List<ADto> dtoList = new ArrayList<>();
2.
3. aRepository.streamAll().forEach(a -> {
4.    ADto dto = new ADto();
5.    dto.setName(a.getName());
6.    dto.setSub(a.getB());
7. })

我的问题是:

如果 A 的实例没有 B(我的意思是使用 LEFT OUTER JOIN 的 SQL 查询,因为实体图返回 B 的空字段)第 6 行对数据库执行第二个 SQL 查询,例如

从 b 中选择 proxy_b_1.id、proxy_b_1.description 作为 proxy_b_1;

实际上,我们已经知道该特定实例 A 下的实例 B 没有值。它也在调试模式下显示。但是为什么它会进行第二次 SQL 查询呢?我怎样才能减轻这种情况?我的意思是如果我做一个实体图查询,如果嵌套 B 存在,这对我来说就足够了。如果不存在,则不执行额外查询。我怎样才能做到这一点?

标签: springhibernatejpalazy-loadingentitygraph

解决方案


在存储库方法中指定实体图并键入EntityGraphType.LOAD

@Repository
public interface ARepository extends CrudRepository<A, Integer> {

  @EntityGraph(value = "subGraph", type = EntityGraphType.LOAD)
  List<A> streamAll();

}

推荐阅读