title: Safely clearing Hibernate session in the middle of large transaction
body: <p>I am using Spring+Hibernate for an operation which requires creating and updating literally hundreds of thousands of items. Something like this:</p>
  
  <pre><code>{
     ...
     Foo foo = fooDAO.get(...);
     for (int i=0; i&lt;500000; i++) {
        Bar bar = barDAO.load(i);
        if (bar.needsModification() &amp;&amp; foo.foo()) {
           bar.setWhatever("new whatever");
           barDAO.update(bar);
           // commit here
           Baz baz = new Baz();
           bazDAO.create(baz);
           // if (i % 100 == 0), clear
        }
     }
  }
  </code></pre>
  
  <p>To protect myself against losing changes in the middle, I commit the changes immediately after <code>barDAO.update(bar)</code>:</p>
  
  <pre><code>HibernateTransactionManager transactionManager = ...; // injected by Spring
  DefaultTransactionDefinition def = new DefaultTransactionDefinition();
  def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
  TransactionStatus transactionStatus = transactionManager.getTransaction(def);
  transactionManager.commit(transactionStatus);
  </code></pre>
  
  <p>At this point I have to say that entire process is running in a transaction wrapped into <code>org.springframework.orm.hibernate3.support.ExtendedOpenSessionInViewFilter</code> (yes, this is a webapp).</p>
  
  <p>This all works fine with one exception: after few thousand of updates/commits, entire process gets really slow, most likely due to memory being bloated by ever-increasing amount of objects kept by Spring/Hibernate.</p>
  
  <p>In Hibernate-only environment this would be easily solvable by calling <code>org.hibernate.Session#clear()</code>. </p>
  
  <p>Now, the questions:</p>
  
  <ul>
  <li>When is it a good time to <code>clear()</code>? Does it have big performance cost?</li>
  <li>Why aren't objects like <code>bar</code> or <code>baz</code> released/GCd automatically? What's the point of keeping them in the session after the commit (in the next loop of iteration they're not reachable anyway)? I haven't done memory dump to prove this but my good feeling is that they're still there until completely exited. If the answer to this is "Hibernate cache", then why isn't the cache flushed upon the available memory going low?</li>
  <li>is it safe/recommended to call <code>org.hibernate.Session#clear()</code> directly (having in mind entire Spring context, things like lazy loading, etc.)? Are there any usable Spring wrappers/counterparts for achieving the same?</li>
  <li>If answer to the above question is true, what will happen with object <code>foo</code>, assuming <code>clear()</code> is called inside the loop? What if <code>foo.foo()</code> is a lazy-load method?</li>
  </ul>
  
  <p>Thank you for the answers.</p>