title: Is Hibernate batching updates
body: <p>So this my maiden question so here it goes... The idea is I am doing a large number of update statements to a database table. In sql it would be a simple
  <code> <code>update table_name set col1 = 123 where col2 = 456 and col1 is null</code>
  </code>. Since there are millions of these it is best thought to batch some of these together. I followed directions here:
  <br>
  <a href="http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html" rel="nofollow">http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html</a>
  <br>
  and a few other pages I've randomly found here on stackoverflow and other places but they all read similar. 
  My idea was to not do a read but do just the update directly and keep looping like this:<br>
  <code></p>
  
  <pre><code>  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();
      }
  </code></pre>
  
  <p></code>
  So the understanding here is that flush will cause every 20 updates to commit and then the clear empties first level cache to avoid the OutOfMemory exception. </p>
  
  <p>So far a config I have 
  <code></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt;
  
  &lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
      &lt;!-- SQL dialect --&gt;
      &lt;property name="dialect"&gt;org.hibernate.dialect.Oracle10gDialect&lt;/property&gt; 
  
      &lt;!-- Database connection settings --&gt; 
      &lt;property name="connection.driver_class"&gt;oracle.jdbc.driver.OracleDriver&lt;/property&gt; 
      &lt;property name="connection.url"&gt;jdbc:oracle:thin:@dev264.oracle.XXXX.com:1521:DEV264&lt;/property&gt;
      &lt;property name="connection.username"&gt;XXXX&lt;/property&gt;
      &lt;property name="connection.password"&gt;XXX&lt;/property&gt;
      &lt;property name="connection.shutdown"&gt;true&lt;/property&gt;
  
      &lt;!-- JDBC connection pool (use the built-in one) --&gt;
      &lt;property name="connection.pool_size"&gt;1&lt;/property&gt; 
  
      &lt;!-- Enable Hibernate's automatic session context management --&gt;
      &lt;property name="current_session_context_class"&gt;thread&lt;/property&gt;
  
      &lt;!-- Disable the second-level cache  --&gt; 
      &lt;property
       name="cache.provider_class"&gt;org.hibernate.cache.NoCacheProvider&lt;/property&gt;
  
      &lt;!-- disable batching so HSQLDB will propagate errors correctly. --&gt;
      &lt;property name="jdbc.batch_size"&gt;20&lt;/property&gt; 
  
      &lt;!-- Echo all executed SQL to stdout --&gt;
      &lt;property name="show_sql"&gt;true&lt;/property&gt; 
  
    &lt;/session-factory&gt;
  &lt;/hibernate-configuration&gt;
  </code></pre>
  
  <p></code>
  Show sql is enabled for debugging purposes. So what I don't get or am not seeing is when I set in log4j
  <code></p>
  
  <pre><code>&lt;logger name="org.hibernate.transaction"&gt;
      &lt;level value="debug"/&gt;
      &lt;appender-ref ref="file"/&gt;
      &lt;appender-ref ref="console"/&gt;
  &lt;/logger&gt;
  </code></pre>
  
  <p></code>
  I only see <br>
  <code></p>
  
  <pre><code>[DEBUG] [main] [org.hibernate.transaction.JDBCTransaction] [commit] 
  [DEBUG] [main] [org.hibernate.transaction.JDBCTransaction] [commit] 
  [DEBUG] [main] [org.hibernate.transaction.JDBCTransaction] [commit] 
  </code></pre>
  
  <p></code>
  at the very end of the log file and not occurring when the 'flush' is occurring. So what I am wondering is whether the commit is really being called every 20 records and whether I am building up too many objects in memory and will I get OutOfMemory in production when this runs being that I don't have hundreds of thousands of test records. </p>