【发布时间】:2011-03-05 12:29:46
【问题描述】:
下面的代码可以运行,但是 Hibernate 永远不会放开它对任何对象的控制。调用session.clear() 会导致有关获取连接类的异常,并且在检索下一个对象之前调用session.evict(currentObject) 也无法释放内存。最终我耗尽了我的堆空间。
检查我的堆转储,StatefulPersistenceContext 是指向我的对象的所有引用的垃圾收集器的根。
public class CriteriaReportSource implements JRDataSource {
private ScrollableResults sr;
private Object currentObject;
private Criteria c;
private static final int scrollSize = 10;
private int offset = 1;
public CriteriaReportSource(Criteria c) {
this.c = c;
advanceScroll();
}
private void advanceScroll() {
// ((Session) Main.em.getDelegate()).clear();
this.sr = c.setFirstResult(offset)
.setMaxResults(scrollSize)
.scroll(ScrollMode.FORWARD_ONLY);
offset += scrollSize;
}
public boolean next() {
if (sr.next()) {
currentObject = sr.get(0);
if (sr.isLast()) {
advanceScroll();
}
return true;
}
return false;
}
public Object getFieldValue(JRField jrf) throws JRException {
Object retVal = null;
if(currentObject == null) { return null; }
try {
retVal = PropertyUtils.getProperty(currentObject, jrf.getName());
} catch (Exception ex) {
Logger.getLogger(CriteriaReportSource.class.getName()).log(Level.SEVERE, null, ex);
}
return retVal;
}
}
【问题讨论】:
-
我在Hibernate reference 中看到了这样的例子,但是,
session.flush()在session.clear()之前被调用。你能试试它是否有影响吗? -
它是什么数据库?并非所有都支持真正的光标滚动。另外,我没有看到您关闭 ScrollableResults。
-
关于flush before clear问题,没有效果。由于我没有更新数据库,因此没有任何意义。如果我正在更新,它会阻止我在清除时倾倒所有内容。 (我确实对此进行了测试以回答您的问题。)
-
查看结果集部分 - 可能是 MySql JDBC 驱动程序将其全部加载到内存中:dev.mysql.com/doc/refman/5.0/en/…。另请查看 useCursorFetch。以下是更多信息(另请参阅 cmets):benjchristensen.com/2008/05/27/…
标签: java performance hibernate orm batch-file