Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 大事务中间安全休眠会话的安全清除_Java_Hibernate_Spring_Orm - Fatal编程技术网

Java 大事务中间安全休眠会话的安全清除

Java 大事务中间安全休眠会话的安全清除,java,hibernate,spring,orm,Java,Hibernate,Spring,Orm,我正在使用Spring+Hibernate进行一项操作,该操作需要创建和更新成百上千个条目。大概是这样的: { ... Foo foo = fooDAO.get(...); for (int i=0; i<500000; i++) { Bar bar = barDAO.load(i); if (bar.needsModification() && foo.foo()) { bar.setWhatever("new

我正在使用Spring+Hibernate进行一项操作,该操作需要创建和更新成百上千个条目。大概是这样的:

{
   ...
   Foo foo = fooDAO.get(...);
   for (int i=0; i<500000; i++) {
      Bar bar = barDAO.load(i);
      if (bar.needsModification() && foo.foo()) {
         bar.setWhatever("new whatever");
         barDAO.update(bar);
         // commit here
         Baz baz = new Baz();
         bazDAO.create(baz);
         // if (i % 100 == 0), clear
      }
   }
}
在这一点上,我必须说,整个流程都在一个事务中运行,该事务被包装到
org.springframework.orm.hibernate3.support.ExtendedOpenSessionInViewFilter
(是的,这是一个webapp)

这一切都很好,只有一个例外:在几千次更新/提交之后,整个过程变得非常缓慢,很可能是由于Spring/Hibernate保存的对象数量不断增加而导致内存膨胀

在只有Hibernate的环境中,通过调用
org.Hibernate.Session#clear()
可以很容易地解决这个问题

现在,问题是:

  • 什么时候是清除()的好时机?它的性能成本大吗
  • 为什么像
    bar
    baz
    这样的对象不能自动释放/GCd?在提交之后将它们保留在会话中有什么意义(在迭代的下一个循环中,它们无论如何都无法访问)?我还没有做内存转储来证明这一点,但我的好感觉是,它们仍然存在,直到完全退出。如果答案是“Hibernate cache”,那么为什么可用内存不足时缓存没有刷新
  • 直接调用
    org.hibernate.Session#clear()
    是否安全/推荐(记住整个Spring上下文,比如延迟加载等)?是否有任何可用的Spring包装器/对应物来实现相同的功能
  • 如果上述问题的答案为真,那么假设在循环中调用了
    clear()
    ,那么对象
    foo
    会发生什么情况?如果
    foo.foo()
谢谢你的回答

什么时候是清除()的好时机?它的性能成本大吗

刷新更改后,以固定的时间间隔,理想情况下与JDBC批处理大小相同。本文档介绍了本章中有关以下内容的常用习惯用法:

使新对象持久化时 刷新()然后清除()会话 定期检查以控制尺寸 一级缓存的

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();
Session Session=sessionFactory.openSession();
事务tx=会话.beginTransaction();

对于(int i=0;i我只想指出,在清除会话后,如果您想继续使用会话中的某些对象,您必须
session.refresh(obj)
它们才能继续

否则将出现以下错误:

org.hibernate.NonUniqueObjectException

感谢您澄清这个Pascal!我也在做多个大的插入。偶尔添加代码刷新和清除会话只会使我的代码运行快4倍!请在回答中用“`为了更好的可读性-
session.refresh(obj)
org.hibernate.NonUniqueObjectException