Sunday, October 17, 2010

GORM gotcha: Many to Many mapping causing new Domain to be saved

Hi All

I came across a new Grails GORM subtle gotcha this week.

I was creating a new Domain object and it was still getting persisted to the database even though i was not calling save().

This is not normal behavior for NEW objects. As you may or may not be aware this is the behavior when updating objects though. So i was quite surprised by this and did some trials in trying to fix the problem.

First calling discard() on my NEW object was the first try. But that was a guess and i knew really it would not work. Because that object not yet associated with the session. And it didn't. So i finally found the problem.

This was all to do the the many to many relationship that was setup on the domain object.

So for example i have somethings like this:

class Location {

static hasMany = [posters:Poster]

String name

}

class Poster {

static belongsTo = [Location]

static hasMany = [locations:Location]

String name

}




So in my controller i allow a user to select multiple locations. These locations all get added to the new Poster in this line of code:

Poster poster = new Poster(params)




So if i then have some business logic that decides that i do not want to create this new Poster i just need to not call save right. Turns out that is wrong.

Because of the many to many relationship between Location and Poster. Poster has been assoiated with the locations. So the locations are now dirty and will get persisted at the end of the transaction. This will cascade to my new Poster and save it.

So to fix this you need to discard the Location objects so they do not save your Poster object.

Poster poster = new Poster(params)

if(businessLogicValidate() == false){

poster.locations.each{Location l ->
l.discard();
}

}else{

poster.save()

}





Hope this helps someone.

2 comments:

DJ said...

I would think the behavior is more due to the "belongsTo" relationship which implies ownership and cascading deletes/updates.

This can probably more gracefully be handled be re-evaluating the use of the belongsTo relationship between the two classes or explicitly defining the relationship to restrict the cascade of belongsTo only to deletes.

dissertation writing help said...

You’re truly a excellent webmaster. The site loading speed is remarkable. It seems that you're doing any unique trick. In addition, The contents are masterpiece. you have done a outstanding job on this subject!