【问题标题】:Hibernate Stored Procedure invocation leads to OutOfMemoryHibernate 存储过程调用导致 OutOfMemory
【发布时间】:2011-10-26 15:21:46
【问题描述】:

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

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

我从休眠文档中知道,您不能使用 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 中的存储过程来管理大型数据集检索。

万分感谢

【问题讨论】:

  • 为什么要返回 200 万行?建议您批量处理。

标签: hibernate stored-procedures large-data


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 2019-02-13
      • 2010-10-24
      相关资源
      最近更新 更多