2013-02-12 2 views
1

Am использование Grails 2.0.3 с базой данных по умолчанию h2 и имеет следующий класс домена пользователя:Grails доменного класс ограничение модификация вызывает исключение

class User { 
    transient springSecurityService 

    String username 
    String password 
    boolean enabled 
    boolean accountExpired 
    boolean accountLocked 
    boolean passwordExpired 

    Preferences preferences 
    Company company 
    Personal personal 

    static constraints = { 
     username email: true, blank: false, unique: true 
     password blank: false 
     preferences unique: true 
     company  unique: true 
     personal unique: true 
    } 

    static mapping = { 
     password column: '`password`' 
    } 

    Set<Role> getAuthorities() { 
     UserRole.findAllByUser(this).collect { it.role } as Set 
    } 

    def beforeInsert() { 
     encodePassword() 
    } 

    def beforeUpdate() { 
     if (isDirty('password')) { 
      encodePassword() 
     } 
    } 

    protected void encodePassword() { 
     password = springSecurityService.encodePassword(password) 
    } 
} 

В контроллере откладывает пользователь, используя следующий код:

userInstance.save(flush: true) 

Теперь, во второй половине дня, я понял, что поле пароля должно иметь ограничение размера и, следовательно, изменен класс домена так, чтобы он стал следующим образом (только изменение в ограничениях):

class User { 
    transient springSecurityService 

    String username 
    String password 
    boolean enabled 
    boolean accountExpired 
    boolean accountLocked 
    boolean passwordExpired 

    Preferences preferences 
    Company company 
    Personal personal 

    static constraints = { 
     username email: true, blank: false, unique: true 
     password blank: false, size: 6..15 
     preferences unique: true 
     company  unique: true 
     personal unique: true 
    } 

    static mapping = { 
     password column: '`password`' 
    } 

    Set<Role> getAuthorities() { 
     UserRole.findAllByUser(this).collect { it.role } as Set 
    } 

    def beforeInsert() { 
     encodePassword() 
    } 

    def beforeUpdate() { 
     if (isDirty('password')) { 
      encodePassword() 
     } 
    } 

    protected void encodePassword() { 
     password = springSecurityService.encodePassword(password) 
    } 
} 

Впоследствии я сгенерировал виды и контроллеры снова. Теперь, когда я пытаюсь сохранить объект пользователя от контроллера, используя:

userInstance.save(flush: true) 

Я получаю следующее исключение:

Класса: org.hibernate.AssertionFailure сообщения: нулевой идентификатор в login.User (не сбрасывайте сеанс после возникновения исключения)

Любая помощь будет оценена по достоинству.

Info: Если я удалю ограничение размера из нового/модифицированного класса, то сохранение происходит нормально.

+0

проверить, если [это] (https://community.jboss.org/thread/186341) помощь? – uchamp

+0

Ограничение выглядит отлично. Можете ли вы опубликовать весь стек и, возможно, часть кода контроллера? – lucke84

ответ

-1

Я столкнулся с той же проблемой, используя Grails 3.1.12. Это то, что я узнал и как я это решил.

Проблема:

Вы пытаетесь поставить ограничение размера на поле, которое собирается быть enconded. Это означает, что пароль, например «admin5», будет завершен в конце жизненного цикла домена как закодированный pwd. Например, db сохранит pwd как: «$ 2a $ 10 $ dn7MyN.nsU8l05fMkL/rfek/d1odko9H4QUpiNp8USGhqx9g0R6om».

Процесс проверки применит ограничение размера к незанятому pwd (шаг проверки на жизненный цикл домена), который пройдет, потому что pwd, введенный пользователем, находится в этом диапазоне. но в методе save() (шаг устойчивости на жизненном цикле домена) pwd будет закодирован перед вставкой или обновлением. Метод enconding создаст pwd с размером, большим, чем ваше ограничение, и Hibernate не сможет выполнить assert() для размера pwd.

Решение:

Используйте ограничение MinSize, если вам не нужно беспокоиться о MaxSize

static constraints = { 
    password blank: false, minSize:6 
} 

Если вам необходимо проверить MaxSize, то я рекомендую вам сделать проверку на вашей службы или Controller перед созданием экземпляра домена.

Смежные вопросы