代码之家  ›  专栏  ›  技术社区  ›  Daniel Engmann

春季配置服务/资源.groovy没有休眠会话

  •  3
  • Daniel Engmann  · 技术社区  · 14 年前

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

    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(也在第一个应用程序的插件中)。所以我们把这项特殊服务添加到资源.groovy在grails app/conf/spring下:

    beans = {
            taskService( SpecialTaskService )
    }
    

    但现在我们打电话时出现了HibernateeException”任务.保存()“在特殊服务中: org.hibernate.hibernate异常:没有绑定到线程的Hibernate会话,配置不允许在此创建非事务会话

    我们知道我们可以将SessionFactory注入到SpecialService中,但是当我们调用sessionFactory.currentSession会话我们也有同样的例外。

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

    1 回复  |  直到 14 年前
        1
  •  5
  •   Burt Beckwith    14 年前

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

    import org.springframework.transaction.annotation.Transactional
    
    @Transactional
    class SpecialTaskService extends TaskService {
    
       @Override
       void doSomething(Task task) {
          // 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()
          }
       }
    }