如何获取深度嵌套的@ * ToOne避免n + 1休眠问题

时间:2019-01-09 23:32:00

标签: hibernate jpa spring-data-jpa

我有一个实体A,其中包含与实体B的@OneToOne关系。 实体B又与实体C具有@OneToOne关系:

A
| 
|--B  @OneToOne
   |
   |--C   @OneToOne

我需要选择实体A的所有数据以及实体B的某些字段。实体C的字段必须忽略。

知道在Hibernate中,* ToOne关系的默认获取类型为EADGER,当在实体A上调用条件Api的getResultList时,将执行N + 1查询(3选择)。

我正在通过Oracle DB通过Spring Boot使用Spring Data JPA。

为避免此问题并仅执行单个查询,我配置了从实体A到实体B的右连接获取。

使用这种配置,我希望可以解决该问题,但是我注意到休眠执行两个选择而不是一个。按照提取中的配置,它将实体A和实体B检索到同一查询中,但执行额外的查询以加载C。

要解决此问题,我还需要为实体C配置正确的联接提取。

这是正确的方法吗? 我很麻烦,因为这是一个简单的案例,但是在复杂的案例中,具有许多关系和嵌套元素会发生什么呢? 有没有办法忽略嵌套关系?

我还尝试与@LazyToOne一起在实体A上使用右连接获取(在编译时进行插入)。但是它总是执行两个查询:

query.getResultList()上的第一个是正确的查询,并正确检索了所有必需的数据。

第二个是当我尝试使用getB()访问B实体时由Hibernate触发的。该查询的行为很奇怪:它从实体A检索实体B的ID。

类似: 从a中选择b.id。 ID =?

我不知道为什么要执行这个额外的查询!

如何以优雅的方式解决问题?

谢谢

0 个答案:

没有答案