my service layer methods are transactional, when i use ExecutorService and submit task to threads, i cannot pass servicelayer as parameter to each threads, as i get error
Dec 14, 2009 10:40:18 AM com.companyx.applicationtest.applicationtestcompanyx.services.threadtestRunnable run
SEVERE: null
org.hibernate.HibernateException: No Hibernate Session bound to thread, and conf
iguration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSessio
n(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactor
yImpl.java:542)
my service layer
ExecutorService executor = Executors.newFixedThreadPool(10);
for (final Object item : CollectionsTest{
executor.submit(new threadtestRunnable((Long)item,collectionAfterfiltered,this)); //'this' is service layer
}
- should i pass the service layer to each thread like this?
- what is the proper way to do it, i need each thread to call method in service layer? (i’m using spring)
Generally, as said in the comments, transactions shouldn’t be run in multiple threads. However, there are cases, where it is acceptable.
If you create your thread using
new, it is not part of the spring context. Hence, when the method creating the thread finishes, your transaction interceptor will close the transaction (and session, eventually), and you will get the above exception.(For more details – Spring docs, see “Lookup injection”)
You need to create your threads within the spring context. And since you are probably creating them from a
singletonbean, it is the rare case of creatingprototypebeans from asingletonbean. So in order to create a thread in the spring context, you can use:You should also map your
ThreadtestRunnableclass in theapplicationContext.xmlor annotate it as@Component("myThreadBean").Then define an
abstractmethod on your main bean namedcreateThreadand returning your thread class. Annotate your run method with@Transactional(or define the appropriate aop rules), and try it. Perhaps you will need to setpropagation=Propagation.REQUIRES_NEW"in your@Transactional. If anything is wrong, get back here.