事务服务中的grails LazyInitializationException

时间:2011-12-13 12:45:28

标签: grails gorm

我有问题。我的服务是grails中的事务性的:

class MyService {

   static transactional = true

   Set<Furniture> getFurniture(Long idHouse) {
      return MyHouse.get(idHouse).getFurniture()
   }
}

在我的控制器中,我有:def myService,我致电myService.getFurniture(id)

即使我的服务是交易性的,我也会得到:LazyInitializationException 我使用的是Grails 2.0.0.RC3 THX。

2 个答案:

答案 0 :(得分:2)

当您在事务中时,整个时间都有一个打开的会话,并且延迟加载的集合将能够在引用时解析。但是你只是返回未初始化的集合,一旦它返回到控制器,它就会与加载它的Hibernate会话断开连接。

所以你只需要初始化集合,有几个选项。一种是调用size()方法:

Set<Furniture> getFurniture(Long idHouse) {
   def furniture = MyHouse.get(idHouse).furniture
   furniture.size() // force eager init
   furniture
}

这会强制Hibernate进入数据库并填充集合。这依赖于副作用 - 最好的方法是调用Hibernate.initialize()

import org.hibernate.Hibernate
...

Set<Furniture> getFurniture(Long idHouse) {
   def furniture = MyHouse.get(idHouse).furniture
   Hibernate.initialize furniture
   furniture
}

答案 1 :(得分:1)

即使您的服务类是事务性的,也可能会出现延迟初始化异常。当服务方法完成执行时,将关闭事务。所以你在控制器端有分离的对象。这不是grails问题。

在众议院域类


static mapping = {
    furniture lazy:false
}

这将提供无论何时查询房屋,它都会附带它的家具

或者您可以设置特定查询的fetchmode


def house = criteria.list{
    ...
    fetchMode('furniture', FetchMode.EAGER)
}