Multithreading Grails2.0.1外部工作线程中的Hibernate异常

Multithreading Grails2.0.1外部工作线程中的Hibernate异常,multithreading,hibernate,grails,Multithreading,Hibernate,Grails,我有一个Grails2.0.1应用程序,我生成了工作线程。我的工作线程使用GORM从MySql读取/写入域对象。假设访问数据库的代码不在HTTP请求中,我将为save()创建一个Hibernate会话,如下所示: MyClass.withTransaction { status -> myClass.save() } 我这样做是为了解决“没有绑定到线程的Hibernate会话”问题 这在Grails1.3.7上运行良好。我目前正试图升级到Grails2.0.1,但看到了一个我不理

我有一个Grails2.0.1应用程序,我生成了工作线程。我的工作线程使用GORM从MySql读取/写入域对象。假设访问数据库的代码不在HTTP请求中,我将为save()创建一个Hibernate会话,如下所示:

MyClass.withTransaction { status ->
    myClass.save()
}
我这样做是为了解决“没有绑定到线程的Hibernate会话”问题

这在Grails1.3.7上运行良好。我目前正试图升级到Grails2.0.1,但看到了一个我不理解的异常

下面的堆栈跟踪显示了异常

尽管我识别出异常,并通常通过上面显示的“withTransaction”技术解决它,但让我感到困惑的是,它发生在我没有创建的工作线程上

Exception in thread "pool-12-thread-2" 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.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
at org.codehaus.groovy.grails.orm.hibernate.SessionFactoryProxy.getCurrentSession(SessionFactoryProxy.java:145)
at org.codehaus.groovy.grails.orm.hibernate.validation.HibernateDomainClassValidator.validate(HibernateDomainClassValidator.java:51)
at org.codehaus.groovy.grails.validation.GrailsDomainClassValidator.validate(GrailsDomainClassValidator.java:121)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.ValidatePersistentMethod.doInvokeInternal(ValidatePersistentMethod.java:119)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.invoke(AbstractDynamicPersistentMethod.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
at org.codehaus.groovy.grails.orm.hibernate.HibernateGormValidationApi.validate(HibernateGormEnhancer.groovy:702)
at com......MyClass.validate(MyClass.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventListener$7.call(ClosureEventListener.java:282)
at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventListener$7.call(ClosureEventListener.java:267)
at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventListener.doWithManualSession(ClosureEventListener.java:302)
at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventListener.onPreUpdate(ClosureEventListener.java:267)
at org.codehaus.groovy.grails.orm.hibernate.EventTriggeringInterceptor.onPreUpdate(EventTriggeringInterceptor.java:164)
at org.codehaus.groovy.grails.orm.hibernate.EventTriggeringInterceptor.onPersistenceEvent(EventTriggeringInterceptor.java:89)
at org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:46)
at org.springframework.context.event.SimpleApplicationEventMulticaster$1.run(SimpleApplicationEventMulticaster.java:92)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
我希望有人能启发我:

  • 此工作线程池的来源是什么
  • 为什么要执行预更新事件(当我相信我的线程中的保存已经成功地进行了验证和保存时)
  • 我是否可以以某种方式配置我的应用程序,使这些外国工作线程不存在
  • 如果无法实现#3,我如何在我不“拥有”的工作线程代码中执行与“withTransaction”等价的操作

  • Grails 2.0.1文档说“Grails现在在刷新底层Hibernate会话时执行验证例程,以确保没有无效对象被持久化”。我现在认为,我在上面的堆栈跟踪中显示的线程可能是刷新会话并执行(冗余?)的Hibernate write-behind线程验证已经在我的线程中执行。我仍然不知道如何处理这个线程上缺少hibernate会话的问题(特别是如果它确实是写后会话刷新线程)。对于分析工具或JConsole来说,这可能是一项很好的任务,因此您可以观察应用程序中线程的运行情况。异常消息末尾可能有线索?“并且配置不允许在此创建非事务性线程”.也许你写的法拉盛背后的理论是正确的,但不管出于什么原因,它试图创建一个休眠会话,但却不能?