java - 我们如何测试 JPA/Hibernate 中的 N+1 问题?

标签 java hibernate jpa regression-testing

我有一个 N+1 问题,我想编写某种自动化回归测试,因为它对性能影响很大。

我想过监视 EntityManager 并验证其方法 createQuery() 仅被调用一次,但 Hibernate 不使用它来初始化惰性关系,因此它不起作用。我还可以尝试关闭存储库和服务之间的 JPA 事务(或分离我的实体)并查找异常,但这确实是一个丑陋的想法。

为了给我们一个框架,假设我们有一个非常简单的父子模型:

@Entity
public class Parent {
    …
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
    private Collection<Child> children;
}

@Entity
public class Child {
    …
    @ManyToOne
    private Parent parent;
}

还有一个非常简单的服务:

public class MyService {
    …
    public void doSomething(Long parentId) {
        Parent parent = …; /* retrieve Parent from the database */
        doSomeOtherThing(parent.getChildren());
    }
}

从数据库中检索父项可以使用以下两个查询:

SELECT parent FROM Parent parent WHERE parent.id = :id;
SELECT parent FROM Parent parent JOIN FETCH parent.children WHERE parent.id = :id;

如何编写一个测试,当我使用第一个查询检索父实体而不是第二个查询时,该测试会崩溃?

最佳答案

作为选项,您可以验证测试中的查询数量(获取、更新、插入)

 repository.findById(10L);

 SessionFactory sf = em.getEntityManagerFactory().unwrap(SessionFactory.class);
 Statistics statistics = sf.getStatistics();

 assertEquals(2L, statistics.getQueryExecutionCount());

参见hibernate statistic

关于java - 我们如何测试 JPA/Hibernate 中的 N+1 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55872771/

相关文章:

java - Spring Boot 测试 - 让应用程序运行更长时间

Java数据输入流

java - Spring Controller /服务/存储库中的泛型

java - 在 servlet 中通过 Hibernate 连接数据库

mysql - java.lang.IllegalStateException : Attempting to execute an operation on a closed EntityManagerFactory 错误

java - 如何将对象添加到 Java 列表中?

java - 有没有所谓的自运行应用程序?

java - Hibernate 架构在部署时自动删除

java - 通过使用 JPA/Hibernate 的方法访问 @Id 字段时防止代理初始化

java - 如何预先加载实体列表?