簡體   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