Hibernate join fetch 执行 N+1,如何解决?
Hibernate join fetch does an N+1, how to fix it?
我有这个查询:
@NamedQuery(
name = "org.mygovscot.stars.model.UserNeed.findAll", query =
"SELECT un FROM UserNeed un " +
"LEFT JOIN FETCH un.services "
)
通过从服务到用户需求的映射:
<set name="userNeeds" table="service_userNeed">
<key column="service_id"/>
<many-to-many column="userNeed_id" class="UserNeed"/>
</set>
以及从 UserNeed 到服务的映射:
<set name="services" table="service_userNeed">
<key column="userNeed_id"/>
<many-to-many column="service_id" class="Service"/>
</set>
也就是说,它是双向多对多。
我是这样查询的:
currentSession()
.getNamedQuery("org.mygovscot.stars.model.UserNeed.findAll")
.list();
我的理解是 "join fetch" 会急切地获取关联,从而避免进行 N+1 查询。然而,结果是 Hibernate 做了 N+1 来获取所有的 UserNeeds。
这是怎么回事? UserNeed 还与其他实体有一些关联,我没有将其包含在联合提取中,我是否还需要联合提取它们才能在单个查询中完成所有操作?
您可能希望将至少一个集合指定为 lazy loaded。
在查询中将另一个关联集合添加为 'join fetches' 修复了它,整个事情 运行 在 1 个查询中。我认为使用查询会覆盖默认的获取策略,但事实上还有其他关系没有被连接获取意味着 Hibernate 以不同的方式对待它们。
我仍然有兴趣听听关于调整获取策略是否也有帮助的评论,也就是说,我是否应该将获取策略设置为 'join'?无论如何,N+1 现在以一种或另一种方式固定。
我有这个查询:
@NamedQuery(
name = "org.mygovscot.stars.model.UserNeed.findAll", query =
"SELECT un FROM UserNeed un " +
"LEFT JOIN FETCH un.services "
)
通过从服务到用户需求的映射:
<set name="userNeeds" table="service_userNeed">
<key column="service_id"/>
<many-to-many column="userNeed_id" class="UserNeed"/>
</set>
以及从 UserNeed 到服务的映射:
<set name="services" table="service_userNeed">
<key column="userNeed_id"/>
<many-to-many column="service_id" class="Service"/>
</set>
也就是说,它是双向多对多。
我是这样查询的:
currentSession()
.getNamedQuery("org.mygovscot.stars.model.UserNeed.findAll")
.list();
我的理解是 "join fetch" 会急切地获取关联,从而避免进行 N+1 查询。然而,结果是 Hibernate 做了 N+1 来获取所有的 UserNeeds。
这是怎么回事? UserNeed 还与其他实体有一些关联,我没有将其包含在联合提取中,我是否还需要联合提取它们才能在单个查询中完成所有操作?
您可能希望将至少一个集合指定为 lazy loaded。
在查询中将另一个关联集合添加为 'join fetches' 修复了它,整个事情 运行 在 1 个查询中。我认为使用查询会覆盖默认的获取策略,但事实上还有其他关系没有被连接获取意味着 Hibernate 以不同的方式对待它们。
我仍然有兴趣听听关于调整获取策略是否也有帮助的评论,也就是说,我是否应该将获取策略设置为 'join'?无论如何,N+1 现在以一种或另一种方式固定。