Ant's
Ant's

Reputation: 13811

Why is GORM performing cascading delete, even if I omit the belongsTo keyword?

I have the following domain classes:

Holiday:

class Holiday {
    String justification
    User user
    //static belongsTo = User
        static constraints = {
        }
}

User:

class User {
    String login
    String password
    static hasMany = [ holidays : Holiday ]
        static constraints = {
    }
}

I have created a one-many relationships between Holiday and User. Note that I haven't included belongsTo on the Holiday class. Now I have written the following integration test:

void testWithoutBelongsTo() {       
        def user1 = new User(login:"anto", password:"secret")
        user1.save()
        def holiday1 = new Holiday(justification:"went to trip")
        holiday1.save()
        user1.addToHolidays(holiday1)
        assertEquals 1, User.get(user1.id).holidays.size()
        user1.delete()
        assertFalse User.exists(user1.id)
        assertFalse Holiday.exists(holiday1.id)
    }

Clearly in the above test case, I'm deleting only the user1 instance, but when I run with assert statements I can see that GORM have implicitly deleted holiday1, too. And my Test cases have PASSED! How this can happen, even though I haven't given belongsTo keyword in Holiday class?

I'm using Grails version 1.3.7.

Upvotes: 0

Views: 169

Answers (2)

mjs
mjs

Reputation: 22389

You should save holiday after adding it to the user.

Upvotes: 0

Antoine
Antoine

Reputation: 5198

holiday1 was never saved as it does not validate: property user is neither set nor nullable.

Here is how your code in Holiday.groovy should look like:

class Holiday {
    String justification
    User user
    //static belongsTo = User
    static constraints = {
        user(nullable: true)
    }
}

And your test, with property user set properly in holiday1:

void testWithoutBelongsTo()
{
    def user1 = new User(login:"anto", password:"secret")
    user1.save(failOnError: true)
    def holiday1 = new Holiday(justification:"went to trip", 
                               user: user1) // Set user properly
    holiday1.save(failOnError: true)
    user1.addToHolidays(holiday1)
    assert 1, User.get(user1.id).holidays.size()
    holiday1.user = null  // Unset user as otherwise your DB
                          // won't be happy (foreign key missing)
    user1.delete()
    assert ! User.exists(user1.id)
    assert Holiday.exists(holiday1.id)
 }

In order to eliminate validation errors quickly in your tests, always use save(failOnError: true). It will throw an exception if your object do not validate.

Upvotes: 3

Related Questions