我面临两个问题:N + 1个查询和内存不足(OOM)。
我通过分页和延迟加载解决了OOM:
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Set<Employee> employees;
但是当我使用延迟加载时,发生了N + 1个查询。因此,我尝试将EntityGraph
用作https://www.baeldung.com/spring-data-jpa-named-entity-graphs。但是,根据我的研究和本地测试,EntityGraph
总是渴望加载NamedAttributeNode
字段-关联字段,我想将其延迟加载:
@NamedEntityGraph(name = "Department",
attributeNodes = {
@NamedAttributeNode("employees")
})
所以有什么办法可以同时获得它们吗?使用EntityGraph
避免N + 1,并使用延迟加载以避免OOM?
使用EntityGraph
,您的所有NamedAttributeNode
关联都将在带有Join
子句的1个查询中加载。启用sql日志以查看hibernate在不同情况下用于加载实体的查询数量
logging.level.org.hibernate.SQL=DEBUG
[您将看到使用@OneToMany(fetch = FetchType.EAGER)
不使用EntityGraph
会为每个雇员单独分隔select
,但是使用EntityGraph
只会执行1个“选择”>
也不要忘记在存储库中指定实体图名称,例如:
@EntityGraph(value = "Department")
List<Department> findAll();