Grails 在spring/resources.groovy中配置的服务没有Hibernate会话

Grails 在spring/resources.groovy中配置的服务没有Hibernate会话,grails,Grails,我们有一个带有插件的应用程序,其中包含一项服务: public class TaskService { public void doSomething( Task task ) { // do something with task task.save(); } } 这个很好用 对于有特殊要求的“特殊”客户,我们有第二个应用程序,其中包含来自第一个应用程序的插件,另一个插件为该客户提供特殊服务,扩展了原始服务并覆盖了一些方法: public

我们有一个带有插件的应用程序,其中包含一项服务:

public class TaskService {

    public void doSomething( Task task ) {
        // do something with task
        task.save();
    }
}
这个很好用


对于有特殊要求的“特殊”客户,我们有第二个应用程序,其中包含来自第一个应用程序的插件,另一个插件为该客户提供特殊服务,扩展了原始服务并覆盖了一些方法:

public class SpecialTaskService extends TaskService{

    @Override
    public void doSomething( Task task ) {
        // do something special with task
        task.save();
    }
}
在第二个应用程序中注入taskService的每个地方,我们现在都希望有SpecialTaskService(也在第一个应用程序的插件中)。因此,我们将特殊服务添加到grails app/conf/spring下的resources.groovy中:

beans = {
        taskService( SpecialTaskService )
}
但现在,当我们在特殊服务中调用“task.save()”时,会出现HibernateException: hibernate.HibernateException:没有绑定到线程的hibernate会话,并且配置不允许在此创建非事务会话

我们知道可以将SessionFactory注入SpecialService,但是当我们调用SessionFactory.currentSession时,我们会得到相同的异常

当我们在resources.groovy中配置服务时,也会发生异常,该服务不扩展另一个服务


有没有办法让这个特殊服务具有某种“hibernateSessionAware”功能,这样我们就可以对域对象调用save()和merge()

原始服务是事务性的,因此它在方法调用期间保持一个Hibernate会话打开(除非一个会话已经处于活动状态并且已经加入)。因此,您也需要使您的实例具有事务性,因为您只是告诉Spring使用
taskService(SpecialTaskService)

最简单的方法是注释类(如果愿意,也可以注释单个方法):

但您也可以在withTransaction块中包装代码块或整个方法:

class SpecialTaskService extends TaskService {

   @Override
   void doSomething(Task task) {
      Task.withTransaction { status ->
         // do something special with task
         task.save()
      }
   }
}
class SpecialTaskService extends TaskService {

   @Override
   void doSomething(Task task) {
      Task.withTransaction { status ->
         // do something special with task
         task.save()
      }
   }
}