Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to recover from `don't flush the Session after an exception occurs` error?

I have two classes :

User

class User {
    //relationships. . . .
    static belongsTo = [ company : Company, role : Role ]
    static hasMany = [ holidays : Holiday ]
    String login
    String password
        static constraints = {
        login(unique:true,size:6..15)
        }
    String toString() {
        this.login
    }
}

And a another class like this:

Role:

class Role {
    String roleName
    String privilege
    static hasMany = [ user : User ]
        static constraints = {  
        privilege(nullable:true)
        roleName(unique:true)
        }
    String toString() {
        this.roleName
    }
}

I wrote a integration test like this :

            def user1 = new User(login:"aravinth", password:"secret")
            def user2 = new User(login:"anto", password:"secret")
            def user3 = new User(login:"antoa", password:"secret")
            def role1 = new Role(roleName:"manager").save()
            def role2 = new Role(roleName:"devleoper").save()
            role1.addToUser(user1)      
            role1.addToUser(user2)      
            role2.addToUser(user3)  
            assert "manager" == user1.role.roleName

This test works fine. But when I add this following line to my above test code :

def roleMembers = Role.findByRoleName("manager")

I'm getting the error like this :

null id in mnm.schedule.User entry (don't flush the Session after an exception occurs)
org.hibernate.AssertionFailure: null id in mnm.schedule.User entry (don't flush the Session after an exception occurs)
    at org.grails.datastore.gorm.GormStaticApi.methodMissing(GormStaticApi.groovy:108)
    at mnm.schedule.RoleItntegrationTests.testAddingRolesToUser(RoleItntegrationTests.groovy:44)

Whats going on? Where I have been wrong?

I'm using Grails 2.0.

Thanks in advance.

like image 488
Ant's Avatar asked Dec 26 '11 14:12

Ant's


1 Answers

The reason that you are getting this error is that when the statement Role.findBy static method is executed, Hibernate(which is used by grails GORM) checks whether "autoFlush" is required. Since new transient Role objects are present, Hibernate tries to automaically flush the session. However at this point the new user objects are present which haven't yet been associated with a role (which is not nullable in User domain). Therefore while flushing, the user object doesn't pass the validation and hence has a null id as mentioned in the exception.

The way to solve this would be to make all the DB read calls (such as findBy methods) before you start creating/updating entities of the same type.

Another option (although not a very good one ) is to set the session flush mode manual.

    User.withSession{ sessionObj ->
        sessionObj.setFlushMode(FlushMode.MANUAL);
        //put your Role.findBy mthod call here
        sessionObj.setFlushMode(FlushMode.AUTO);

    }
like image 90
Anuj Arora Avatar answered Oct 21 '22 09:10

Anuj Arora