繁体   English   中英

Grails域类约束修改导致异常

[英]Grails domain class constraint modification causing exception

我在默认的h2数据库中使用grails 2.0.3,并具有以下用户域类:

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消息:登录中的id为null。用户条目(发生异常后不要刷新Session)

任何帮助将不胜感激。

信息:如果我从新的/修改的类中删除了大小限制,则保存会很好。

我在使用Grails 3.1.12时遇到了同样的问题。 这就是我发现的以及如何解决的方法。

问题:

您正在尝试将大小约束放到将要确认的字段上。 这意味着像“ admin5”这样的密码将在域生命周期结束时以已编码的pwd身份出现。 例如,数据库会将pwd存储为:“ $ 2a $ 10 $ dn7MyN.nsU8l05fMkL / rfek / d1odko9H4QUpiNp8USGhqx9g0R6om”。

验证过程会将大小约束应用于未编码的pwd(域生命周期中的验证步骤),由于用户键入的pwd在该范围内,因此将通过。 但是在save()方法(域生命周期中的持久性步骤)上,pwd将在插入或更新之前进行编码。 enconding方法将创建一个大小大于您的约束的pwd,并且Hibernate将使pwd大小的assert()失败。

解:

如果您不必担心maxSize,请使用minSize约束

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

如果需要验证maxSize,则建议您在创建域实例之前在Service或Controller层上进行验证。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM