为什么Hibernate有时会忽略FetchMode.JOIN?

Gio*_*ato 5 java optimization hibernate jpa

我有一个@ManyToOne关系的实体,我想用一个查询检索,因此使用@Fetch(FetchMode.JOIN).有时Hibernate不尊重并发布N + 1 SELECT.随着有时我的意思是,因为我不知道是什么触发它,我有案件对不同的查询,这可能发生,或者不一样的类.

这是一个带有我使用的注释的简化实体:

@Entity
public class Employee {

    @ManyToOne
    @Fetch(FetchMode.JOIN)
    private Department department;

}
Run Code Online (Sandbox Code Playgroud)

CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);

Root<Employee> root = criteriqQuery.from(Employee.class);

TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);

List<Employee> employees = typedQuery.getResultList();
Run Code Online (Sandbox Code Playgroud)

我希望一个查询来获取两个EmployeeDepartment,像

select ... from Employee join Department on ...
Run Code Online (Sandbox Code Playgroud)

相反,我得到所有N的Employee第一个选择,然后SELECT是所有Departments的N s(考虑没有缓存).

我发现了许多类似的问题,但他们的答案提出了解决方法,并没有解释为什么会发生这种情况.请避免建议使用延迟加载的答案:这不是我问的问题.

Dra*_*vic 8

规则很简单:查询忽略了获取模式.当您编写查询时,您将告知已加入的内容和未加入的内容.

只有在使用类似方法加载实体EntityManager.find(class, id)或在导航其他实体图并加载其关联时,才会考虑获取模式.

  • 谢谢你!就是这样:Criteria API 忽略 `@Fetch`,但是使用 `Root.fetch()` (即 JPA)我可以实现相同的结果。 (2认同)