Hibernate存储过程调用导致OutOfMemory



我使用Hibernate的命名查询来执行一个存储过程,返回一个非常大的数据集(超过200万行),数据库是Oracle 11g

例如

:Query query = session.getNamedQuery(procName);

我知道从hibernate文档,你不能使用setFirstResult/setMaxResult如上所述http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html。

在100,000行这样的小数据集上一切正常。但是,当我使用1,000,000进行测试时,我得到了OutOfMemory错误。

从查询对象中,我得到一个listtiterator。我假设数据只被获取一次,我遍历侦听器(query.list().listIterator())

我没有配置第二级缓存。在处理Oracle存储过程时,这些设置有帮助吗?

query.setCacheMode(org.hibernate.CacheMode.IGNORE); query.setFetchSize(1000);
query.scroll(org.hibernate.ScrollMode.FORWARD_ONLY);

基本上,我如何在Hibernate中使用存储进程管理大型数据集检索。

百万由于

这完全取决于您如何处理从查询返回的数据。如果将其视为典型的查询—也就是说,对其调用list()并将结果存储在Collection中—那么您将使用这么多行来突破内存限制。关键是要批量获取和加工它们。我认为使用Hibernate这样做的典型方法是将结果作为scrolllableresults获取,并记住定期刷新()和清除()会话,因为它充当一级缓存,并将存储正在加载的所有对象。在Hibernate中查找有关批处理的描述,但要注意不要与Hibernate的批处理获取和相关概念混淆。它们是两种不同的动物。

与其说是Hibernate的问题,不如说是内存使用的问题。我也遇到过类似的情况,JMS消息在处理少量数据时工作得很好,但当处理更多数据时,一切都崩溃了。因为我怀疑你需要所有的2mm记录在内存中一次,看看你是否可以得到存储过程更新采取限制和偏移量,以便它可以返回数据片,而不是只有整个数据集。

最新更新