Wednesday 30 May 2012

Grails many-to-many deletes

This is an interesting problem I've had recently when trying to delete a Child object that's a member of a many-to-many relationship.

So, the classes are as follows:

class List {

String name
String description

static hasMany = [tasks:Task]
}

class Task {

String name
String description

static belongsTo = List
static hasMany = [lists:List]
}


Pretty simple right? But try calling the delete method of the "Task" controller and you'll soon run into problems. The problem is that when the child object is deleted, it's references in the parent aren't deleted. If you're not sure what this means, just keep an eye on the database contents and you'll see how after deleting the child object you end up with a bunch of foreign key pointers that are invalid now.

The solution is to add some code like the following in the delete method right?

taskInstance.lists.each{
  it.removeFromTasks(taskInstance)
}


However, if you try this you'll get a "java.util.ConcurrentModificationException". Which is telling you that Java doesn't allow you to change the contents of a collection (array, list, set etc...) while iterating over that same collection.

The solution which I found is kind of kludgey, but does the job:

def tmp = []
tmp.addAll(taskInstance.lists)
tmp.each{
it.removeFromTasks(taskInstance)
}


This somehow doesn't "feel" right. It feels like it shouldn't be this hard to delete a child object and have the parent object be updated at the same time.


No comments: