Grails:addTo() 方法是否不适用于新创建的对象?

Grails: Does the addTo() method not work on newly created objects?

我正在使用 Grails 2.5.5,这里有一个简单的场景:A 有很多 B。

所以我有一个事务服务方法,它基本上执行以下操作:

A a 
if (isNew) {
    a = new A()
} else {
    a = A.findById(someId)
} 

List<B> bList = getBsFromSomeOtherMethod() 
bList.each { a.addToBs(it) } 

a.save(failOnError: true) 

有趣的是,如果我创建一个新对象(如上面逻辑中的 isNew 为真),那么在调用 save() 时会出现以下异常:reassociated object has dirty collection reference (or an array)

但是,如果我得到一个已经存在于数据库中的对象,那么一切都会完美无缺。

我发现的解决方法是,如果我在将 Bs 添加到 A 之前保存新对象,那么事情就可以了。但我宁愿不必调用 save() 两次,如果调用就在最后,代码会更清晰。

我用谷歌搜索了异常,但似乎无法解释这里发生的事情。
有人可以帮忙解决这个问题吗?

就像其他人在评论中所说的那样,您需要保存对象,以便它存在于数据库中,并且有一个 id。当你有一个 A has many Bs 关系时,数据库中会创建一个新的 table(类似于 a_b)以将 A.id 映射到 B.id,这就是为什么你如果不先保存,就无法将 B 添加到 A

A a 
if (isNew) {
    a = new A()
    a.save()
} else {
    a = A.findById(someId)
} 

List<B> bList = getBsFromSomeOtherMethod() 
bList.each { a.addToBs(it) } 

a.save(failOnError: true)

使用findOrSaveBy进行这样的操作。您将从数据库中获取正确的对象或保留新对象:

def a = A.findOrSaveByField(field)
List<B> bList = getBsFromSomeOtherMethod() 
bList.each { a.addToBs(it) }
a.save(failOnError: true)