如何将 Hibernate 会话绑定到 Grails 中的线程?
我正在用 Grails 编写一个多线程应用程序,附加线程需要访问 GORM/Hibernate。当他们尝试访问 GORM 时,我收到错误“org.hibernate.HibernateException:没有 Hibernate 会话绑定到线程,并且配置不允许在此处创建非事务会话”。
好吧,公平地说,有人可以指导我设置线程以进行访问的最佳方法吗?错误消息听起来几乎像是您只需要更改一些配置选项,但我感觉,事情并不那么简单......
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Grails 应用程序中有一个名为“persistenceInterceptor”的 bean 可以用于此目的。
有关如何使用 JMS 插件的示例,请参阅:
http://github.com/gpc/grails-jms/blob/master/src/groovy/grails/plugin/jms/listener/adapter/PersistenceContextAwareListenerAdapter.groovy#L21
这是界面:
https://github.com/grails/grails-core/blob/master/grails-core/src/main/groovy/grails/persistence/support/PersistenceContextInterceptor.java
和 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
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
您需要将任何 GORM 调用放入 withTransaction 闭包中。摘自多线程讨论的示例
https:// fbflex.wordpress.com/2010/06/11/writing-batch-import-scripts-with-grails-gsql-and-gpars/
单线程
多线程
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
multi threaded
withNewSession 也可以工作。就我而言,我的更新优先级较低,最后一个更新始终可以“获胜”。
version: false
在这里也很重要,以避免 StaleObjectException:withNewSession will also work. In my case, I have low priority updates where the last update can always "win".
version: false
is also important here in order to avoid the StaleObjectException:卢克·戴利给出了正确的答案。不幸的是,链接已更改。因此,我将更新他的答案并提供一个代码示例以使该答案独立。
Grails 应用程序中有一个名为persistenceInterceptor 的bean,可用于初始化Hibernate 的持久性上下文/会话。您可以将 bean 注入控制器/服务类之一并启动一个新线程,例如使用以下代码片段。
您将在 GitHub 上的 Grails JMS 插件。
PersistenceContextInterceptor 接口也可以在 GitHub 上找到。
Luke Daley gave the right answer. Unfortunately, the links have changed. Thus, I'll update his answer and provide a code example to make this answer self-contained.
There is a bean in Grails applications called
persistenceInterceptor
that can be used for initializing the persistence context / session for Hibernate. You can inject the bean into one of your controller / service classes and start a new thread, e.g. using the following code snippet.You'll find an exemplary implementation in the Grails JMS plug-in on GitHub.
The PersistenceContextInterceptor interface can be found on GitHub, too.