【发布时间】:2019-04-26 17:54:48
【问题描述】:
我有一个 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;
当我使用第一个查询而不是第二个查询检索父实体时,我如何编写一个崩溃的测试?
【问题讨论】:
-
@Sambit 我不是要求解决 N+1 问题,而是要求一种自动检测它的方法。我已经阅读了您所指的问题,但在那里找不到答案。
-
您可以尝试检查
getChildren()是否实际返回PersistentCollection,如果是,则wasInitialized()是否返回true。如果该持久性集合未初始化,则任何访问都可能导致延迟加载(可能在某些情况下不会发生这种情况,例如,在调用size()时并取决于您的映射 - 例如,它是否额外延迟,但是很有可能)。
标签: java hibernate jpa regression-testing