Grails / Hibernate如何解开在http会话中存储对象导致的无会话打开的异常

时间:2014-06-25 07:21:02

标签: hibernate session grails

我知道在http会话中存储对象是一个坏主意,因为OSIV无法解决当我尝试访问此对象的集合类型属性时导致的LazyInitializationException。

不幸的是,我一直在http会话中存储一些对象,例如currentUser

我将当前用户存储在http会话中,如:

session.currentUser = loggedUser

用户拥有类似

的规则集合
session.currentUser.rules

正如预期的那样,当我尝试访问后续请求中的规则集合时,我得到一个LazyInitializationException异常,因为session.currentUser失去了它的持久化上下文。

即使我正在迁移到在http会话中存储objects'id的正确approch,我也必须找到一个解决方案,以确保访问存储在http session中的对象的collection属性。 t casue LazyInitializationException。

我正在考虑通过覆盖HttpSession的方法来解决方案:

HttpSession.metaClass.getProperty { name ->
        if(name.equals("currentUser")){
            def userId = delegate.getProperty(name).id
            def userInstance = Utilisateur.get(userId)
            println 'in metaclass currentUser ' + userInstance.isAttached()
            return userInstance
        }else{
            return  delegate.getProperty(name)
        }
    }

而不是直接返回currentUser,我使用Get()方法从hibernate会话中检索附加对象。

此解决方案似乎有效, 你认为这是个好主意吗?

2 个答案:

答案 0 :(得分:0)

最简单的解决方案是使rules关联非懒惰

static mapping = {
  rules lazy:false
}

将在加载用户时为用户预先加载所有规则,因此以后无需再参考hibernate会话。

答案 1 :(得分:0)

在将对象放入会话之前,应确保对象已完全初始化。最好的方法是确保您热切地查询。例如,如果Userrules,您可以这样做:

session.currentUser = User.findByLogin("blah", [fetch:[rules:"eager"])