【问题标题】:Grails/Hibernate How to untangle the no-session-opened exception caused by storing object in http sessionGrails/Hibernate 如何解决在 http session 中存储对象导致的 no-session-opened 异常
【发布时间】:2014-06-25 07:21:01
【问题描述】:

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

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

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

session.currentUser = loggedUser

一个用户有一个类似的规则集合

session.currentUser.rules

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

即使我正在迁移到在 http 会话中存储对象 id 的正确方法,我也必须找到一种解决方案,以确保对存储在 http 会话中的对象的集合属性的访问不' t 导致 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 session grails


    【解决方案1】:

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

    static mapping = {
      rules lazy:false
    }
    

    它会在用户加载时预先加载用户的所有规则,因此以后无需参考休眠会话。

    【讨论】:

    • 你好罗伯茨,但我仍然想要一个惰性获取模式。
    【解决方案2】:

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

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

    【讨论】:

    • 你好rocher,感谢您的回复。但是您认为我的解决方案可以正常工作吗(覆盖 HttpSession 类的 getProperty())?
    • 另一个问题:急切的 finder (User.findByLogin("blah", [fetch:[rules:"eager"])) 是否等同于 Hibernate.initialize(usr.rules)?谢谢
    猜你喜欢
    • 2014-03-13
    • 2013-04-05
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    相关资源
    最近更新 更多