java - 使用 Spring data JPA EntityGraph 和 NamedAttributeNode 字段的 LAZY 加载模式

标签 java spring-boot spring-data-jpa out-of-memory lazy-loading

我面临 2 个问题: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 字段 - 关联字段进行急切加载,我希望延迟加载 - 首先不要加载所有数据:

@Entity
@Table(name = "department")
@NamedEntityGraph(name = "Department",
        attributeNodes = {
                @NamedAttributeNode("employees")
        }
)
public class Department implements Serializable {
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id")
    private Set<Employee> employees;
}

那么有什么办法可以同时获得它们吗?使用EntityGraph避免N+1和延迟加载以避免OOM?

更新: EntityGraph 可以与 Pageable 有效地配合使用吗?我的意思是不要在 JOIN 查询中加载所有数据。

最佳答案

使用 EntityGraph,所有 NamedAttributeNode 关联都将加载到带有 Join 子句的 1 个查询中。启用sql日志查看hibernate在不同场景下加载实体有多少查询

logging.level.org.hibernate.SQL=DEBUG

您将看到,在不使用 EntityGraph 的情况下使用 @OneToMany(fetch = FetchType.EAGER) 会在单独的 select 查询中加载员工(N + 1),但使用 EntityGraph 它只执行 1 select ... join

另外,不要忘记在存储库中指定实体图名称,例如:

@EntityGraph(value = "Department")
List<Department> findAll();

更新: Spring DATA 分页在数据库端不起作用。它将获取所有数据,然后在内存中进行过滤。这就是它的工作原理。有一些解决方法,请检查此链接:

How can I avoid the Warning "firstResult/maxResults specified with collection fetch; applying in memory!" when using Hibernate?

Avoiding "HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!" using Spring Data

VladMihalcea Blog The best way to fix the Hibernate HHH000104

对我来说,解决方案可以是创建自定义存储库并使用 EntityManager 手动构建查询。

关于java - 使用 Spring data JPA EntityGraph 和 NamedAttributeNode 字段的 LAZY 加载模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60109680/

相关文章:

java - 将编码的 base64 图像转换为 Android 中的文件对象

java - 性能暴力哈希 C++ Java

java - Spring REST 中将日期作为请求参数

aspectj - Spring 的 AspectJ 模式缓存与 AspectJ 模式事务

java - 使用本地PC作为服务器

java - 如何在通用jframe中使用多个jpanel

java - JPA:使用服务和多个存储库的正确方法

java - Spring 数据JPA : Generate dynamic query

spring-boot - Spring 注释在Kotlin中不起作用

java - NoSuchBeanDefinitionException:当我使用自动配置时,没有名为 'elasticsearchTemplate'的bean可用