title: spring - Hibernate session management with multiple transactions in a cron job?
body: <p>In a spring/hibernate application I have some cronjobs running every night. One of them should do its work in multiple transactions like this:</p>
  
  <pre><code>@Scheduled(cron = "...")
  public void cron ( ) 
  {
      batchJob();
  }
  
  @Transactional(propagation = Propagation.NEVER)
  public void batchJob ( )
  {
      List&lt;Customer&gt; customers = getCustomers();
      for (Customer customer : customers
      {
          doSomething(customer);
      }
  }
  
  @Transactional(readOnly = true)
  protected List&lt;Customer&gt; getCustomers ( )
  {
      return customerRepository.getCustomers();
  }
  
  @Transactional
  protected void doSomething (Customer customer )
  {
           // LazyInitializationException 
           customer.getAddress();
           // ...
  }
  </code></pre>
  
  <p>parts of my spring config: </p>
  
  <pre><code>&lt;!-- Transaction --&gt;
  &lt;tx:annotation-driven mode="aspectj" /&gt;
  
  &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;
      &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>The key point here is that I don't want to have one long running transaction. So first I get all customers and call a transactional method for each customer. ( I hope the code posted is enough to understand the problem)</p>
  
  <p>Of course I get a LazyInitializationException because Spring is closing the session when the Transaction around 'getCustomer' is committed. </p>
  
  <p>possible solutions i can think of:</p>
  
  <ul>
  <li><p>I can use an OpenSessionInViewInterceptor but this is a web component</p></li>
  <li><p>I can reattach the detached object with session.merge(customer) </p></li>
  <li><p>Is this a case for Propagation.Nestedtransaction? What are the semantics of nested transaction? Most databases don't have nested transaction (postgresql does but I have never used it, it is called two phase commit </p></li>
  <li><p>I can rewrite the method to consume customerId and load the customer again inside the second transaction</p></li>
  </ul>
  
  <p>Now I have two questions concerning my problem:</p>
  
  <ol>
  <li><p>How can you write a test to reproduce the bug above? </p></li>
  <li><p>How can I easily span an open session around this or what is the best way to do a bunch of work in multiple transactions? </p></li>
  </ol>