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

Grails/Hibernate如何解开将对象存储在http会话中导致的未打开会话异常,hibernate,session,grails,Hibernate,Session,Grails,我知道在http会话中存储对象是个坏主意,因为当我尝试访问该对象的集合类型属性时,OSIV无法解决LazyInitializationException引起的异常 不幸的是,我一直在http会话中存储一些对象,例如currentUser: 我将当前用户存储在http会话中,如下所示: session.currentUser = loggedUser 用户有一个规则集合,如 session.currentUser.rules 正如预期的那样,当我尝试在后续请求中访问规则集合时,我得到一个Laz

我知道在http会话中存储对象是个坏主意,因为当我尝试访问该对象的集合类型属性时,OSIV无法解决LazyInitializationException引起的异常

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

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

session.currentUser = loggedUser
用户有一个规则集合,如

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

即使我正在迁移到在http会话中存储对象id的正确方法,我也必须找到一个解决方案,以确保对存储在http会话中的对象的集合属性的访问不会导致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)
        }
    }
我使用Get()方法从hibernate会话中检索连接的对象,而不是直接返回currentUser

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

最简单的解决方案是使
规则
关联非惰性

static mapping = {
  rules lazy:false
}

它将在加载用户时预先加载用户的所有规则,因此以后无需返回到hibernate会话。

在将对象放入会话之前,应确保对象已完全初始化。做到这一点的最佳方法是确保您急切地进行查询。例如,如果您
用户
拥有
规则
,您会:

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

你好,罗伯茨,但我仍然想有一个懒惰的获取模式。你好,罗彻,谢谢回复。但您认为我的解决方案可以正常工作(覆盖HttpSession类的getProperty())吗?另一个问题:是否一个急切的查找程序(User.findByLogin(“blah”,“fetch:[规则:”急切的“])等同于Hibernate.initialize(usr.rules)?谢谢