gpt4 book ai didi

hibernate - Grails 2.5.6事务回滚

转载 作者:行者123 更新时间:2023-12-02 14:00:03 24 4
gpt4 key购买 nike

我主要要做的是如果发生错误或域类无效,请返回编辑页面。
我有一个User对象,其中包含一个Person对象作为属性。

我的 Controller 如下所示:

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)
}
}
}

返回编辑页面时,我总是会收到一个异常,该异常告诉我没有打开的Session可以加载person对象。

为了快速解决这一问题,我在用户对象的映射中添加了 lazy:false,但不幸的是整个项目的运行速度非常慢,因此我不得不删除 lazy:false映射选项。

现在,我试图找到一种使它再次运行的方法。

Hibernate为什么要在回滚时关闭 session ?

如何重新打开 session ?

编辑:

我尝试在设置回滚之前渲染 View :
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

最佳答案

我在DomainClasses中创建了一个方法来加载所需的所有对象,并在返回编辑页面时调用此方法:

 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()
loadObject(person)
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()
loadObject(user)
return render(view: 'edit', model:[user:user, person:person], params: params)
}
}
}

加载类型为domainClass的所有Properties的Method看起来像这样:
void loadObject(Object object, List<Object> loadedObjects = []){
loadedObjects.add(object)
for(MapEntry propertyEntryMap in object.properties){
Object property = propertyEntryMap?.value
if(grailsApplication.isDomainClass(property.getClass())){
if(!loadedObjects.contains(property))
loadObject(property, loadedObject)
}
}
if(object.hasProperty("hasMany")){
for(def manyProperty in object.hasMany){
for(Object property in object."${manyProperty.key}"){
if(grailsApplication.isDomainClass(property.getClass())){
if(!loadedObjects.contains(property))
loadObject(property, loadedObject)
}
}
}
}
}

您可能遇到的唯一问题是hasMany关系可能很大,并且放慢了速度。

为了解决此问题,我向DomainClass添加了一个属性,该属性包含应加载的hasMany关系:
static lazyProperties = ['addresses']

此属性影响 loadObject方法,该方法将遍历该List中的属性:
void loadObject(Object object, List<Object> loadedObjects = []){
loadedObjects.add(object)
for(MapEntry propertyEntryMap in object.properties){
Object property = propertyEntryMap?.value
if(object.hasProperty('lazyProperties')){ // check if object contains the property 'lazyProperties'
if(object?.lazyProperties?.contains(propertyEntryMap.key))
continue
}
if(grailsApplication.isDomainClass(property.getClass())){
if(!loadedObjects.contains(property))
loadObject(property, loadedObject)
}
}
if(object.hasProperty("hasMany")){
for(def manyProperty in object.hasMany){
if(object.hasProperty('lazyProperties')){ // check if object contains the property 'lazyProperties'
if(object?.lazyProperties?.contains(manyProperty.key))
continue
}
for(Object property in object."${manyProperty.key}"){
if(grailsApplication.isDomainClass(property.getClass())){
if(!loadedObjects.contains(property))
loadObject(property, loadedObject)
}
}
}
}
}

关于hibernate - Grails 2.5.6事务回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47072654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com