这里的问题与Hibernate无关,而是与JPA有关。
在 JPA 1.0 之前,Hibernate 3 对所有关联都使用延迟加载。
然而,JPA 1.0 规范使用FetchType.LAZY
仅适用于收藏协会:
-
@OneToMany,
- @ManyToMany
-
@ElementCollection)
The @ManyToOne and @OneToOne协会使用FetchType.EAGER
默认情况下,从性能角度来看这非常糟糕。
这里描述的行为称为 [N+1 查询问题][5],发生这种情况是因为 Hibernate 需要确保@ManyToOne
关联在将结果返回给用户之前初始化。
现在,如果您使用直接获取entityManager.find
,Hibernate可以使用LEFT JOIN来初始化FetchTYpe.EAGER
协会。
但是,当执行未显式使用 JOIN FETCH 子句的查询时,Hibernate 将不会使用 JOIN 来获取FetchTYpe.EAGER
关联,因为它不能改变您已经指定如何构建的查询。所以,只能使用二次查询。
修复方法很简单。只需使用FetchType.LAZY
对于所有协会:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "invoice_number", insertable = false, updatable = false)
private Invoice invoice;
更多,您应该使用超坚持实用程序断言 JPA 和 Hibernate 执行的语句数。