gpt4 book ai didi

hibernate - LazyInitializationException每个请求有多个事务

转载 作者:行者123 更新时间:2023-12-02 15:27:23 24 4
gpt4 key购买 nike

我有grails服务,该服务在给定的域对象上执行操作。该操作可能会失败,并且如果失败了,我希望该操作的事务回滚。

我还具有一个 Controller ,该 Controller 遍历此域类的所有实例,并在每个实例上调用服务。如果对给定对象的服务操作失败,我想继续处理其余的域对象,每个域对象都在其自己的独立事务中进行。

为了明确起见,我需要在一所交易中处理一所房屋内的所有房间(请参阅下面的域类),但是每所房屋要进行单独的交易。

有没有办法做到这一点?下面是我尝试的操作,但是在对其中一个对象进行的操作失败后,尝试处理后续对象时,在以下情况下,我不断收到异常消息。事务回滚时,可能是Hibernate session 正在关闭吗?

(注意:对我来说,切换到紧急加载可能不是一个选择,因为我们的实际域类实际上包含多个hasMany关系。)

异常(exception):

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.blah.House.rooms, no session or session was closed

码:
class DataService {
static transactional = true

def processStuff(House house){
house.rooms.each{
if(someCondition){
throw new RuntimeException('failed') // will cause txn to roll back
}
}
}
}

class DataController {

def dataService

def doSomething(){
def houses = House.findAll()
houses.each{ house ->
dataService.processStuff(house)
}
render(view:'someView')
}
}

class House {
def hasMany = [rooms: Room]
}
class Room {
}

最佳答案

根本问题是,回滚事务时,将清除Hibernate session (从而使所有延迟加载的集合无效)。在Grails docs中记录了此行为(及其解决方法)。

就我而言,最好的解决方案是在每个事务开始时重新加载父对象。这将重新初始化延迟加载集合。

class DataService {
static transactional = true

def processStuff(House house){

house = House.get(house.id) // <-- reload to reinstate lazy collections

house.rooms.each{
if(someCondition){
throw new RuntimeException('failed') // will cause txn to roll back
}
}
}
}

关于hibernate - LazyInitializationException每个请求有多个事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25880062/

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