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:
@Service
public class BackgroundJobService {
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
public void startJob(Runnable runnable) {
threadPoolTaskExecutor.execute(runnable);
}
}
Then have the ThreadPoolTaskExecutor
configured in Spring:
<bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
This is all working great. However, the problem comes from Hibernate. Inside my runnable, queries only half work. I can do:
MyObject myObject = myObjectRepository.findOne()
myObject.setSomething("something");
myObjectRepository.save(myObject);
But if I have lazy loaded fields, it fails:
MyObject myObject = myObjectRepository.findOne()
List<Lazy> lazies = myObject.getLazies();
for(Lazy lazy : lazies) { // Exception
...
}
I get the following error:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.stackoverflow.MyObject.lazies, could not initialize proxy - no Session
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.
- Is there a way to start a new session manually from within the session?
- Or a way to tell the thread pool to do it for me?
- What's the standard practice for doing this kind of work?
I've been able to work around it a little by doing everything from inside a @Transactional
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.
Thanks.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…