【发布时间】:2017-11-02 10:13:14
【问题描述】:
如果发生错误或域类无效,我要做的主要事情是返回编辑页面。
我有一个 User 对象,其中包含一个 Person 对象作为属性。
我的控制器如下所示:
Object update(){
User.withTransaction{status ->
try {
personDaoService?.bindObject(person, params)
person.validate()
} catch(Exception e){
log.error(e.printStackTrace())
status.setRollbackOnly()
}
if(person.hasErrors()){
status.setRollbackOnly()
}
if(status.isRollbackOnly()){
person.discard()
person.refresh()
return render(view: 'edit', model:[user:user, person:person], params: params)
}
try {
userDaoService?.bindObject(person, params)
user.validate()
} catch(Exception e){
log.error(e.printStackTrace())
status.setRollbackOnly()
}
if(status.isRollbackOnly()){
user.discard()
user.refresh()
return render(view: 'edit, model:[user:user, person:person], params: params)
}
}
}
返回编辑页面时,我总是收到一个异常,告诉我没有打开的会话来加载人员对象。
为了快速解决这个问题,我在用户对象的映射中添加了lazy:false,但这导致整个项目运行非常缓慢,因此我不得不删除lazy:false 映射选项。
现在我正试图找到一种方法让它再次工作。
为什么 hibernate 在回滚时关闭会话?
如何重新打开会话?
编辑:
我尝试在设置回滚之前渲染视图:
if(person.hasErrors()){
person.errors.allErrors.each{user.errors.rejectValue("person", "", "${validationTagLib.message(error: it)}")}
render(view: 'edit', model: [user: user], params: params)
status.setRollbackOnly()
return
}
这会导致此异常:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
【问题讨论】:
-
您可以在 status.setRollbackOnly() 之前将人和用户对象/数据存储在一个全局变量中,这样就可以用来渲染您的视图。
-
也可以使用@Transactional注解来更新方法
-
不相关,但
log.error(e.printStackTrace())没有按照您的想法行事。e.printStackTrace()是一个void方法,它将堆栈跟踪转储到标准输出,因此您只记录null。更改为log.error(e.message, e)(替换或增加e.message),它将记录错误消息和堆栈跟踪 -
将对象存储在全局变量中不起作用,@Transactional 注释也不起作用,两者都导致此错误
org.hibernate.LazyInitializationException: could not initialize proxy - no Session -
通过在失败的方法周围添加一个 try and catch 来捕获可抛出的错误 - 首先让页面通过,就好像没有出错一样 - 不是你想要的 - 但会帮助你找到问题并希望修复它 - 我有时会看到这种情况,通常是当你要求的事情无法完成时 - 通常不仅仅是由验证等引起的特定错误