如何从“在异常发生后不刷新会话”恢复?错误? [英] How to recover from `don't flush the Session after an exception occurs` error?

查看:149
本文介绍了如何从“在异常发生后不刷新会话”恢复?错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个课程:

用户

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
    }
}

另一个类如下:

角色

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")

我收到这样的错误:

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?

我正在使用Grails 2.0。

I'm using Grails 2.0.

提前感谢

推荐答案

您收到此错误的原因是,当执行语句Role.findBy static方法时,Hibernate(由Grails GORM使用)会检查autoFlush 是必须的。由于存在新的临时Role对象,Hibernate会尝试自动刷新会话。但是,在这一点上,还存在尚未与角色关联的新用户对象(在用户域中不可为空)。因此,在刷新时,用户对象不会通过验证,因此具有异常中提到的空号。

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.

解决此问题的方法是使所有在开始创建/更新相同类型的实体之前,DB会读取调用(例如findBy方法)

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);

    }

这篇关于如何从“在异常发生后不刷新会话”恢复?错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆