论坛首页 Java企业应用论坛

Hibernate Batch inserts 好像从来没成功过

浏览 9083 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-12-28  
Hibernate 3.1 reference中 “13.1. Batch inserts ”一节提到可以用
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();

来批量增加数据,我试了,100000是没什么问题,但是 200000 就不行了,一样 OutOfMemory. 有人试过用 Hibernate 大批量处理 Insert, Update, Delete 的吗?
   发表时间:2005-12-28  
我用 Connection 来试了试,很快就完成了 20w 数据的输入,哎~ Hibernate

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tran = session.beginTransaction();
        session.setCacheMode(CacheMode.IGNORE);

        PreparedStatement stmt;
        try {
            stmt = session.connection().prepareStatement("INSERT INTO EVENTS(EVENT_DATE, title) VALUES(?,?)");
            for (int i = 0; i < 200000; i++) {
                stmt.setTimestamp(1, new Timestamp(new Date().getTime()));
                stmt.setString(2, "Title["+i+"]");
                stmt.addBatch();
            }
            stmt.executeBatch();
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            tran.rollback();
        }
        tran.commit();
        session.close();
        HibernateUtil.getSessionFactory().close();
0 请登录后投票
   发表时间:2005-12-28  
你的Hibernate操作方式下并没有打开batch功能
0 请登录后投票
   发表时间:2005-12-29  
robbin 写道
你的Hibernate操作方式下并没有打开batch功能


你指的是 <property name="jdbc.batch_size">20</property> 这个选项吗?如果是,我有设置这个属性。

我得到的错误是 java.lang.OutOfMemoryError: Java heap space

通过增大 heap size 应该可以解决问题。

我觉得问题可能是 hibernate 对内存的消耗比较大,JVM 对内存的回收是需要时间的,而且不同的 jvm 算法有些不一样,所以并没有很好的办法去解决。

我现在觉得JDBC 的方式可能也会出现这样的问题,只是 20w 还没有占满 heap space,如果再处理多一些对象,肯定也会 OOM 了
0 请登录后投票
   发表时间:2005-12-29  
另外,我顺便测试了一下StatelessSession,缺少 batch insert 的功能,性能很差
0 请登录后投票
   发表时间:2005-12-29  
iceant 写道
robbin 写道
你的Hibernate操作方式下并没有打开batch功能


你指的是 <property name="jdbc.batch_size">20</property> 这个选项吗?如果是,我有设置这个属性。

我得到的错误是 java.lang.OutOfMemoryError: Java heap space

通过增大 heap size 应该可以解决问题。

我觉得问题可能是 hibernate 对内存的消耗比较大,JVM 对内存的回收是需要时间的,而且不同的 jvm 算法有些不一样,所以并没有很好的办法去解决。

我现在觉得JDBC 的方式可能也会出现这样的问题,只是 20w 还没有占满 heap space,如果再处理多一些对象,肯定也会 OOM 了


我也遇到过类似的问题,感觉hibernate对内存的消耗确实大,不只是回收时间的问题,只要hibernate session还在,就无法回收,我猜想是session里面的引用关系比较复杂。最后采取自动分割batch,跟html结合分段执行,就是action->view-action->view.....才实现所需的效果,比较简陋,不知还有没有更好的办法。
0 请登录后投票
   发表时间:2005-12-29  
iceant 写道
robbin 写道
你的Hibernate操作方式下并没有打开batch功能


你指的是 <property name="jdbc.batch_size">20</property> 这个选项吗?如果是,我有设置这个属性。

我得到的错误是 java.lang.OutOfMemoryError: Java heap space

通过增大 heap size 应该可以解决问题。

我觉得问题可能是 hibernate 对内存的消耗比较大,JVM 对内存的回收是需要时间的,而且不同的 jvm 算法有些不一样,所以并没有很好的办法去解决。

我现在觉得JDBC 的方式可能也会出现这样的问题,只是 20w 还没有占满 heap space,如果再处理多一些对象,肯定也会 OOM 了


只要session.clear()了,Hibernate占用的内存就释放掉了。仔细比较一下你提供的代码,有一个重大区别,每次循环,Hibernate都要new 一个Customer 对象,这些Customer对象只有在GC的时候才会被回收。而你的JDBC代码是没有创建Customer对象,你可以试试在JDBC代码里面new Customer,一样会out of memory。

BTW:批量插入20万条记录,测试程序应该设置JVM参数了 -Xms...
0 请登录后投票
   发表时间:2005-12-29  
lllyq 写道
iceant 写道
robbin 写道
你的Hibernate操作方式下并没有打开batch功能


你指的是 <property name="jdbc.batch_size">20</property> 这个选项吗?如果是,我有设置这个属性。

我得到的错误是 java.lang.OutOfMemoryError: Java heap space

通过增大 heap size 应该可以解决问题。

我觉得问题可能是 hibernate 对内存的消耗比较大,JVM 对内存的回收是需要时间的,而且不同的 jvm 算法有些不一样,所以并没有很好的办法去解决。

我现在觉得JDBC 的方式可能也会出现这样的问题,只是 20w 还没有占满 heap space,如果再处理多一些对象,肯定也会 OOM 了


我也遇到过类似的问题,感觉hibernate对内存的消耗确实大,不只是回收时间的问题,只要hibernate session还在,就无法回收,我猜想是session里面的引用关系比较复杂。最后采取自动分割batch,跟html结合分段执行,就是action->view-action->view.....才实现所需的效果,比较简陋,不知还有没有更好的办法。


这是因为Session一级缓存是强引用导致的。不过话说回来,大批量操作本来就不是O/R Mapping应该去做的事情。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics