Как восстановиться после ошибки «не очищать сессию после возникновения исключения»? - PullRequest
5 голосов
/ 26 декабря 2011

У меня есть два класса:

Пользователь

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

И еще один класс, подобный этому:

Роль :

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

Я написал интеграционный тест следующим образом:

            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

Этот тест работает нормально. Но когда я добавлю следующую строку в мой код теста выше:

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)

Что происходит? Где я был не прав?

Я использую Grails 2.0.

Заранее спасибо.

Ответы [ 2 ]

10 голосов
/ 26 декабря 2011

Причина, по которой вы получаете эту ошибку, состоит в том, что при выполнении статического метода оператора Role.findBy Hibernate (который используется Grails GORM) проверяет, требуется ли "autoFlush". Поскольку присутствуют новые временные объекты Role, Hibernate пытается автоматически очистить сеанс. Однако в этот момент появляются новые пользовательские объекты, которые еще не были связаны с ролью (которая не может быть обнуляемой в пользовательском домене). Поэтому при очистке пользовательский объект не проходит проверку и, следовательно, имеет нулевой идентификатор, как указано в исключении.

Чтобы решить эту проблему, нужно сделать все вызовы чтения из БД (например, методы findBy) до того, как вы начнете создание / обновление сущностей одного типа.

Другой вариант (хотя и не очень удачный) - установить ручной режим сброса сеанса.

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

    }
0 голосов
/ 23 августа 2013

Если вы используете Spring Security Core, такая же ошибка возникает, если вы добавляете ограничение size или создаете пользовательский validator, чтобы проверить, равен ли «пароль» «подтверждению пароля». Решением является использование командного объекта в этих случаях. Этот случай раскрыт здесь .

В общем, эта ошибка может произойти, если некоторые поля имеют значение NULL, когда они не должны быть NULL, но они проходят ограничение (обычно из-за некоторой ошибки в коде). База данных имеет ненулевое правило, поэтому запись не будет создана. Grails покажет эту ужасную ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...