hibernategrailsgroovyassociationsgrails-orm

grails / GORM / hibernate - hasMany map not synchronised on save() of parent


Problem deleting associated entities and having this change persisted to the database.

Have a groovy object parent which has many child entities associated with it. When we find this domain object and set this list to null, and call parent.save(flush:true) the child elements remain in the database. Would have expected these to have been deleted. Any suggestions would be great.

class Parent {

   static hasMany = [child:Child]
   ...
}

and the child:

class Child {

   belongsTo = [Parent]
   ...
}

we add the element and delete:

def child = new Child()

def parent = new Parent(child:child)

parent.save(flush:true)
def id = parent.id //from saved entity

/// in separate transaction

parent = Parent.get(id) //id from above
parent.child = null

parent.save(flush:true)

// check database - child reference still there - expect to have been deleted

Any suggestions about what we've done that wrong would be appreciated. using grails 1.3.5 (latest version).


Solution

  • First thing, you should use child.delete(flush:true) instead of assign null. It's just not approriate. (sorry for the previous mistake)

    I recommend you read Peter Ledbrook series: http://blog.springsource.com/2010/07/02/gorm-gotchas-part-2/ . In your case, search "Deleting children"

    Update: in case you still not read the above article (specifically useful):

    To delete a child, you first need to remove it from the parent collection, then delete it. But it would cause property not null exception since you use belongsTo relation.

    Solution: You can add this into Parent class:

    static mapping = {
     childs cascade: "all-delete-orphan"
    }
    

    The above mapping will help delete all child that don't have a parent. Then you can use

    parent.childs.clear()