How do I properly do a background thread when using Spring Data and Hibernate?
With Spring you don't need your own executor. A simple annotation @Async
will do the work for you. Just annotate your heavyMethod
in your service with it and return void or a Future
object and you will get a background thread. I would avoid using the async annotation on the controller level, as this will create an asynchronous thread in the request pool executor and you might run out of 'request acceptors'.
The problem with your lazy exception comes as you suspected from the new thread which does not have a session. To avoid this issue your async method should handle the complete work. Don't provide previously loaded entities as parameters. The service can use an EntityManager and can also be transactional.
I for myself dont merge @Async
and @Transactional
so i can run the service in either way. I just create async wrapper around the service and use this one instead if needed. (This simplifies testing for example)
@Service
public class AsyncService {
@Autowired
private Service service;
@Async
public void doAsync(int entityId) {
service.doHeavy(entityId);
}
}
@Service
public class Service {
@PersistenceContext
private EntityManager em;
@Transactional
public void doHeavy(int entityId) {
// some long running work
}
}