• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Hibernate + Spring + TimerTask = No Hibernate Session bound to thread

 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,
I'm having a problem with an operation that should be executed with a delay. I tried several things with no success and thought I'm sure someone had this problem before can't find a decent answer. Did you encountered this problem before and can give me a tip?

Basically I have a service bean (let's say EntityService):

All the scheduler does is to create a TimerTask that calls the finishGeneration with the passed id when the specified time has passed (the service implements a special scheduler callback interface to allow this).

generateWithDelay works ok and the entity is saved in DB and the TimerTask is created. However when the callback method is called I get:
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler.invoke(AbstractSessionFactoryBean.java:300)


Is there a problem if the method is called from the Timer thread instead of the webcontainer thread? Because I'm pretty sure that if I call finishGeneration from generateWithDelay it will work.
 
Eduardo Bueno
Ranch Hand
Posts: 155
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem may be in your application context. In a long shot, I suppose you forgot to declare an hibernate property:

 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey thank you. I did indeed forgot to specify that. After you told me I read about this setting on hibernate docs so I added to my session factory bean these properties:

Unfortunately this didn't help. I still get the same exception in the same situation.
 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the end I solved this by opening a transaction programatically in the run method of the TimerTask.
However I'm still curious why it didn't worked declaratively and if it is possible to make it work this way.
 
Cristian Vrabie
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Found the problem:
When I provide the callback to the scheduler I do:

As you know, in Spring the transaction is started by the proxy that wraps the entityService. However, because I use JDK proxies, this won't be the proxy, but the proxy target (the original service). So when the callback is invoked it bypasses the transaction mechanism completely. The trick is to provide the actual proxy to the scheduler. I did this by letting EntityService implement ApplicationContextAware and BeanNameAware and fetching the proxy from the applicationContext at initialization:
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic