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