I'm writing a multi-threaded application in Grails and the additional threads need access to GORM/Hibernate. When they try to access GORM I get the error "org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here".
OK fair enough, can someone guide me on the best way to set the threads up to have access? The error message almost sounds like you just need to change some config options yet I sense, it is not so simple...
The Session object is not thread-safe, meaning it was never intended to be accessed by more than one thread. For this it uses NO thread-safe mechanism: no mutex. no volatile reads.
23) Does Hibernate Session interface is thread-safe in Java? No, Session object is not thread-safe in Hibernate and intended to be used with-in single thread in the application.
Spring opens a new Hibernate Session at the beginning of the request. These Sessions are not necessarily connected to the database. Every time the application needs a Session, it will reuse the already existing one.
There is a bean in Grails applications called “persistenceInterceptor” that can be used for this.
See this example from the JMS plugin on how to use it:
http://github.com/gpc/grails-jms/blob/master/src/groovy/grails/plugin/jms/listener/adapter/PersistenceContextAwareListenerAdapter.groovy#L21
Here is the interface:
https://github.com/grails/grails-core/blob/master/grails-core/src/main/groovy/grails/persistence/support/PersistenceContextInterceptor.java
And Hibernate impl:
https://github.com/grails/grails-data-mapping/blob/master/grails-datastore-gorm-support/src/main/groovy/org/grails/orm/hibernate4/support/HibernatePersistenceContextInterceptor.java
You need to put any GORM calls in a withTransaction closure. An example taken from a discussion of multi threading at https://fbflex.wordpress.com/2010/06/11/writing-batch-import-scripts-with-grails-gsql-and-gpars/
Single threaded
user = User.findByUsername( photo.username )
multi threaded
User.withTransaction{
user = User.findByUsername( photo.username )
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With