title: How do I properly do a background thread when using Spring Data and Hibernate?
body: <p>I'm building a simple Tomcat webapp that's using Spring Data and Hibernate. There's one end point that does a lot of work, so I want to offload the work to a background thread so that the web request doesn't hang for 10+ minutes while the work is being done. So I wrote a new Service in a component-scan'd package:</p>
  
  <pre><code>@Service
  public class BackgroundJobService {
      @Autowired
      private ThreadPoolTaskExecutor threadPoolTaskExecutor;
  
      public void startJob(Runnable runnable) {
           threadPoolTaskExecutor.execute(runnable);
      }
  }
  </code></pre>
  
  <p>Then have the <code>ThreadPoolTaskExecutor</code> configured in Spring:</p>
  
  <pre><code>&lt;bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"&gt;
      &lt;property name="corePoolSize" value="5" /&gt;
      &lt;property name="maxPoolSize" value="10" /&gt;
      &lt;property name="queueCapacity" value="25" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>This is all working great. However, the problem comes from Hibernate. Inside my runnable, queries only half work. I can do:</p>
  
  <pre><code>MyObject myObject = myObjectRepository.findOne()
  myObject.setSomething("something");
  myObjectRepository.save(myObject);
  </code></pre>
  
  <p>But if I have lazy loaded fields, it fails:</p>
  
  <pre><code>MyObject myObject = myObjectRepository.findOne()
  List&lt;Lazy&gt; lazies = myObject.getLazies();
  for(Lazy lazy : lazies) { // Exception
      ...
  }
  </code></pre>
  
  <p>I get the following error:</p>
  
  <pre><code>org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.stackoverflow.MyObject.lazies, could not initialize proxy - no Session
  </code></pre>
  
  <p>So it looks like to me (Hibernate newbie) that the new thread doesn't have a session on these home-made threads, but Spring Data is automatically creating new sessions for HTTP Request threads.</p>
  
  <ul>
  <li>Is there a way to start a new session manually from within the session?</li>
  <li>Or a way to tell the thread pool to do it for me?</li>
  <li>What's the standard practice for doing this kind of work?</li>
  </ul>
  
  <p>I've been able to work around it a little by doing everything from inside a <code>@Transactional</code> method, but I'm quickly learning that's not a very good solution, as that doesn't let me use methods that work just fine for web requests.</p>
  
  <p>Thanks.</p>