我有两个实体,Item
和 Data
,以及一个 DTO 类 ItemData
。 ItemData
由 Item
和 Data
组成,没有 JPA 映射。为了检索填充的 ItemData 列表,我在 JPQL 中使用构造函数表达式:
select new my.package.ItemData(i, d)
from Item i, Data d
where i.id = d.itemId
这就是 Hibernate 正在做的事情:它不是同时获取 Item
和 Data
的数据,而是先获取它们的 ID,然后获取 n< 中的数据/em> 单独的选择语句。有没有办法改变这种行为?
Hibernate:
select
item0_.id as col_0_0_,
data1_.id as col_1_0_
from
ITEM item0_,
DATA data1_
Hibernate:
select
item0_.no as no1_0_,
item0_.description as description1_0_,
item0_.organic as bio1_0_,
item0_.gluten as gluten1_0_,
item0_.laktose as laktose1_0_
from
ITEM item0_
where
item0_.id=?
Hibernate:
select
data0_.amount as amount1_3_0_,
data0_.avg as avg3_0_,
data0_.total as total3_0_
from
DATA data0_
where
data0_.id=?
Hibernate:
select
item0_.no as no1_0_,
item0_.description as description1_0_,
item0_.organic as bio1_0_,
item0_.gluten as gluten1_0_,
item0_.laktose as laktose1_0_
from
ITEM item0_
where
item0_.id=?
Hibernate:
select
data0_.amount as amount1_3_0_,
data0_.avg as avg3_0_,
data0_.total as total3_0_
from
DATA data0_
where
data0_.id=?
...and so on...
最佳答案
使用左连接获取怎么样?
我承认我没有使用 CTOR 表达式,但是当我需要获取父实体及其子实体时,我使用了左连接获取,它总是很有魅力。
我只能假设,既然我们在这里处理对象的构造,
Hibernate 不“想要”留下“部分构造”的对象(或者说 - 处于“惰性求值状态”的对象),并且由于您没有使用“左连接获取”执行“急切获取”,因此它执行 N +1 获取:
首先,它获取所有 ID,然后针对每个相关 ID 执行另一次获取。
阅读有关左连接获取的更多信息 here (只需在页面中查找“left join fetch”即可)
关于java - 使用 JPA/Hibernate 构造函数表达式防止 "n+1 selects"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12782029/