java JPA/Hibernate似乎将带有in子句的查询转换为带有=子句的多个查询
为了在合理的时间内收集大量重对象而不造成内存溢出(我指的是具有多个fetchType.eager关系的对象,对于本身具有eager fetched关系的实体),我们实现的一个解决方案是首先选择这些对象的ID,然后根据这些ID选择对象本身
到了优化代码的时候,我们注意到(使用hibernate.show_sql=true
),我们用来收集这些对象的查询(select a from A a where a.id in :ids
)被JPA/Hibernate翻译成数千个形式为select a from ...endless join list... where a.id = ?
的查询
问题如下:
为什么JPA/Hibernate会将带有“in”子句的初始查询转换为带有“=”子句的众多查询。这不是效率低下吗?如果是这样,有没有办法防止这种情况强>
下面是在我们的代码中如何调用查询:
Query q = this.getContext().createQuery("select a from A a where a.id in :ids");
q.setParameter("ids", idList);
return (List<A>) q.getResultList();
# 1 楼答案
尽管我仍然无法解释为什么会为in子句中提供的每个ID生成查询(在我的原始问题中提供),但我在这个博客(https://thoughts-on-java.org/fetch-multiple-entities-id-hibernate/)上找到了解决这个问题的方法。 解决方案包括使用Hibernate的会话API,如下所示:
# 2 楼答案
如果您的
idList
超过1000个元素,您可能会遇到这个特定于Oracle的去优化https://hibernate.atlassian.net/browse/HHH-9299解决这个问题的一种方法是将
idList
分成多个块,对每个块执行一个查询,并连接结果# 3 楼答案
您好,您应该使用setParameterList而不是
setParameter
。 如果要获取完整的实体对象,也不需要在hibernate中使用select