grails之在 spring/resources.groovy 中配置的服务没有 Hibernate session
我们有一个带有包含服务的插件的应用程序:
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();
}
}
在第二个应用程序中注入(inject) taskService 的每个地方,我们现在都希望拥有 SpecialTaskService(也在第一个应用程序的插件中)。所以我们在 grails-app/conf/spring 下的 resources.groovy 添加了特殊服务:
beans = {
taskService( SpecialTaskService )
}
但是现在我们在特殊服务中调用“task.save()”时会得到一个 HibernateException: org.hibernate.HibernateException:没有绑定(bind)到线程的 Hibernate Session,并且配置不允许在此处创建非事务性 session
我们知道我们可以将 SessionFactory 注入(inject)到 SpecialService 中,但是当我们调用 sessionFactory.currentSession 时,我们会得到相同的异常。
当我们在 resources.groovy 中配置一个不扩展另一个服务的服务时,也会发生异常。
有没有办法使特殊服务成为某种“hibernateSessionAware”,以便我们可以在域对象上调用 save() 和 merge()?
请您参考如下方法:
原始服务是事务性的,因此它在方法调用期间保持 Hibernate session 打开(除非一个已经处于事件状态并且它已加入该 session )。因此,您也需要使您的事务成为事务性的,因为您只是告诉 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()
}
}
但您也可以将代码块或整个方法包装在 withTransaction block 中:
class SpecialTaskService extends TaskService {
@Override
void doSomething(Task task) {
Task.withTransaction { status ->
// do something special with task
task.save()
}
}
}
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。