Search code examples
grailsgrails-orm

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


I'm using Grails 2.5.5, and I have a simple scenario here: A has many Bs.

And so I have a transactional service method which basically does the following:.

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) 

The interesting thing is that if I create a new object (as in, isNew is true in the above logic), then I get the following exception when save() is called: reassociated object has dirty collection reference (or an array).

However, if I get an object which already exists in the DB, then everything works perfectly.

The workaround I found is that if I save the new object before adding Bs to A, then things work. But I would rather not have to call save() twice, and the code is just a lot cleaner if the call was just at the end.

I've googled the exception but nothing seems to explain what's going on here.
Can somebody help out with this?


Solution

  • Like others have said in the comments, you need to save the object so it exists in the database, and has an id. When you have a A has many Bs relationship, a new table in the database (something like a_b) is created to map A.id to B.id, which is why you can't add Bs to A without saving first.

    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)