我正在使用Hibernate的命名Query来执行一个存储过程,返回一个非常大的数据集(超过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错误。
从查询对象中,我得到一个listIterator。我假设数据只被提取一次,我遍历了listiterator(query.list().listIterator()
)
我没有配置二级缓存。 在处理Oracle存储过程时,这些设置是否会有所帮助。
query.setCacheMode(org.hibernate.CacheMode.IGNORE);
query.setFetchSize(1000);
query.scroll(org.hibernate.ScrollMode.FORWARD_ONLY);
基本上,我如何使用Hibernate中的存储过程来管理大型数据集检索。
百万谢谢
答案 0 :(得分:1)
这完全取决于您如何处理从查询返回的数据。如果你将它视为一个典型的查询 - 也就是说,在它上面调用list()并将结果存储在Collection中 - 那么你将会破坏那么多行的内存限制。关键是分批获取和处理它们。我相信使用Hibernate这样做的典型方法是将结果作为ScrollableResults并定期记住flush()和clear()会话,因为它充当第一级缓存并将存储所有正在加载的对象。查看Hibernate中批处理的描述,但要注意不要混淆Hibernate的batch fetching及相关概念。他们是两种不同的动物。
答案 1 :(得分:0)
你的问题不是Hibernate而是内存使用问题。我有类似的情况,JMS消息在少量数据的情况下正常工作,然后一切都爆炸了。因为我怀疑你一次需要内存中的所有2mm记录,看看你是否可以更新存储过程以获取限制和偏移量,以便它可以返回数据切片而不是整个数据集。