-1

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

例如: Query query = session.getNamedQuery(procName);

我从休眠文档中知道,您不能使用 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html中所述的 setFirstResult/setMaxResult 。

一切都很好,在像 100,000 行这样的较小数据集上。但是,一旦我使用 1,000,000 进行测试,我就会收到 OutOfMemory 错误。

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

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

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

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

百万谢谢

4

2 回答 2

1

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

于 2011-08-14T02:19:46.020 回答
0

您的问题不是休眠问题之一,而是内存使用问题之一。我遇到过类似的情况,JMS 消息在处理少量数据时运行良好,然后一切都因更多数据而爆炸。由于我怀疑您一次需要内存中的所有 2mm 记录,因此请查看是否可以更新存储的过程以获取限制和偏移量,以便它可以返回数据切片而不是仅返回整个数据集。

于 2011-08-14T04:30:29.700 回答