Monday, September 27, 2010

Replacing a persistent collection in Grails domain object

If I have a domain model set up the following way:

class Site {
    static hasMany = [instances: Instance]
}

class Instance {
    static belongsTo = [Site]
}

and have to perform a task of wiping out a collection of Instances in a Site, including the deletion of all records of Instance, this would be the right way to do it:

site.instances*.delete()
site.instances.clear()
site.save(flush: true)

This may be a bit non-intuitive for such a trivial task, however, if you omit the first delete() call, you'll end up with orphan Instance records. If you omit the clear() call, you'll get this error:

deleted object would be re-saved by cascade (remove deleted object from associations): [Instance]

And of course, site.removeFromInstances() does not take a Collection, and if you loop through it and delete each individual Instance, you'll get a ConcurrentModificationException.