Java Hibernate正在批处理更新吗

Java Hibernate正在批处理更新吗,java,hibernate,batch-updates,Java,Hibernate,Batch Updates,这是我的处女问题,就这样。。。我的想法是对数据库表执行大量update语句。在sql中,这将是一个简单的过程 更新表\u name set col1=123,其中col2=456,col1为空 。由于有数以百万计的此类产品,因此最好将其中的一些产品集中在一起。我按照这里的指示: 我在stackoverflow和其他地方随机找到了一些其他页面,但它们都读到了类似的内容。 我的想法是不进行读取,而是直接进行更新,并保持如下循环: 所以这里的理解是,flush将导致每20次更新提交一次,然后c

这是我的处女问题,就这样。。。我的想法是对数据库表执行大量update语句。在sql中,这将是一个简单的过程
更新表\u name set col1=123,其中col2=456,col1为空
。由于有数以百万计的此类产品,因此最好将其中的一些产品集中在一起。我按照这里的指示:

我在stackoverflow和其他地方随机找到了一些其他页面,但它们都读到了类似的内容。 我的想法是不进行读取,而是直接进行更新,并保持如下循环:

所以这里的理解是,flush将导致每20次更新提交一次,然后clear清空一级缓存以避免OutOfMemory异常

到目前为止,我有一个配置


在日志文件的最末尾,并且在“刷新”发生时不发生。所以我想知道的是,提交是否真的是每20条记录调用一次,我是否在内存中建立了太多的对象,当我没有数十万条测试记录时,我是否会在生产中失去内存

您混淆了
flush()
commit()
flush()
不提交事务。它所做的只是执行update和delete语句,以便在数据库中写入已应用于内存、附加实体以及尚未持久化的更改

在您的情况下,刷新和清除会话是无用的(但无害的),因为您不在内存中应用任何更改,因此会话总是空的


另外,在每次迭代中创建一个新的查询也是无用的。您可以一次又一次地重复使用同一查询。和
detail.trainSummary=null
不正确。它应该是
detail.trainSummary为null

您混淆了
flush()
commit()
flush()
不提交事务。它所做的只是执行update和delete语句,以便在数据库中写入已应用于内存、附加实体以及尚未持久化的更改

在您的情况下,刷新和清除会话是无用的(但无害的),因为您不在内存中应用任何更改,因此会话总是空的


另外,在每次迭代中创建一个新的查询也是无用的。您可以一次又一次地重复使用同一查询。和
detail.trainSummary=null
不正确。应该是
detail.trainSummary为空

我会对上面的答案发表评论,但字数太高了…
好吧,那么至少你没有给我发送这个问题的链接,让我感觉稍微好一点,但我想我明白你的意思
所以这个应用程序的版本就像第三版,很快就会有第四版。注意不要继续重新创建查询。我的原始版本进行了读取(到内存中),然后调用了setter(更改内存中的对象)。在某个地方我有了这个想法,跳过选择,只做更新。因此,如果a执行读取操作,然后更改状态,则需要刷新和清除。由于没有读取,因此没有任何内容需要清除或刷新。因此,我不可能在一级缓存上耗尽内存。我真正关心的是Oracle使用了太多的程序全局区域(PGA)内存,占用了太多的撤消空间。我在这里读到:

因此,每20到100次更新,不要在会话上调用flush,而是在事务上提交。此外,我还应该监视executeUpdate调用中更改的行数,而不仅仅是每次执行查询时计数。所以我最终得到了这样的结果:


我本来会对你上面的答案发表评论的,但是字数太多了…
好吧,那么至少你没有给我发送这个问题的链接,让我感觉稍微好一点,但我想我明白你的意思
所以这个应用程序的版本就像第三版,很快就会有第四版。注意不要继续重新创建查询。我的原始版本进行了读取(到内存中),然后调用了setter(更改内存中的对象)。在某个地方我有了这个想法,跳过选择,只做更新。因此,如果a执行读取操作,然后更改状态,则需要刷新和清除。由于没有读取,因此没有任何内容需要清除或刷新。因此,我不可能在一级缓存上耗尽内存。我真正关心的是Oracle使用了太多的程序全局区域(PGA)内存,占用了太多的撤消空间。我在这里读到:

因此,每20到100次更新,不要在会话上调用flush,而是在事务上提交。此外,我还应该监视executeUpdate调用中更改的行数,而不仅仅是每次执行查询时计数。所以我最终得到了这样的结果:


我的回复太长,无法发表评论。我的回复太长,无法发表评论。
  sessionFactory = new Configuration().configure("finaldetail/hibernate.dev.cfg.xml") 
          .addPackage("com.xxx.app.ftm.domain.event").addAnnotatedClass(FinalTrainDetail.class) 
          .addAnnotatedClass(AbstractDetail.class).addAnnotatedClassFinalTrainDetailWork.class).buildSessionFactory();
      inputStream = new BufferedReader(new FileReader(new File(args[0])));
      session = sessionFactory.openSession();
      transaction = session.beginTransaction(); 
      String s; 
      int count = 0; 
      while ((s = inputStream.readLine()) != null) {
        Query query = session.createQuery("update FinalTrainDetail  detail set detail.trainSummary "
                + "=:summaryId where detail.trainDetail=:detailId and detail.trainSummary=null"); 
        query.setParameter("summaryId", new Long(s.substring(9, 18)));
        query.setParameter("detailId", new Long(s.substring(0, 9)));
        query.executeUpdate();
        count++; 
        if (count % 20 == 0) { 
          log.debug("should commit"); 
          session.flush(); 
          session.clear(); 
        } 
      } 
      transaction.commit();
      System.out.println("exit");
    } catch (IOException e) {
      transaction.rollback();
      log.error(e.toString());
    } catch (Throwable t) {
      System.out.print(t);
      log.error("exception caught during Updateing Offline", t);
      System.exit(2);
    } finally {
      if (inputStream != null)
        inputStream.close();
      session.close();
    }
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
  <session-factory>
    <!-- SQL dialect -->
    <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> 

    <!-- Database connection settings --> 
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
    <property name="connection.url">jdbc:oracle:thin:@dev264.oracle.XXXX.com:1521:DEV264</property>
    <property name="connection.username">XXXX</property>
    <property name="connection.password">XXX</property>
    <property name="connection.shutdown">true</property>

    <!-- JDBC connection pool (use the built-in one) -->
    <property name="connection.pool_size">1</property> 

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache  --> 
    <property
     name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

    <!-- disable batching so HSQLDB will propagate errors correctly. -->
    <property name="jdbc.batch_size">20</property> 

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property> 

  </session-factory>
</hibernate-configuration>
<logger name="org.hibernate.transaction">
    <level value="debug"/>
    <appender-ref ref="file"/>
    <appender-ref ref="console"/>
</logger>
[DEBUG] [main] [org.hibernate.transaction.JDBCTransaction] [commit] 
[DEBUG] [main] [org.hibernate.transaction.JDBCTransaction] [commit] 
[DEBUG] [main] [org.hibernate.transaction.JDBCTransaction] [commit] 
Query query = session.createQuery("update FinalTrainDetail  detail set detail.trainSummary "
      + "=:summaryId where detail.trainDetail=:detailId and detail.trainSummary=null");
  while ((s = inputStream.readLine()) != null) {
    transaction = session.beginTransaction();
    query.setParameter("summaryId", new Long(s.substring(9, 18)));
    query.setParameter("detailId", new Long(s.substring(0, 9)));
    count+=query.executeUpdate();
    if (count % 100 == 0) {
      log.debug("should commit");
      transaction.commit();
    }
  }
  transaction.commit();
  System.out.println("exit");