2013-02-12 19 views
1

上午和具有以下用戶域類:Grails領域類限制修改導致使用默認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在login.User (不要在異常發生後刷新會話)

任何幫助將不勝感激。

信息:如果我從新的/修改過的類中刪除了大小限制,則 保存會正常工作。

+0

檢查[this](https://community.jboss.org/thread/186341)有幫助嗎? – uchamp 2013-02-12 12:57:28

+0

約束看起來很好。你可以發佈整個堆棧跟蹤,也許涉及到控制器的代碼段? – lucke84 2013-02-12 12:57:31

回答

-1

我遇到了同樣的問題,使用Grails 3.1.12。這就是我發現的以及我是如何解決它的。

問題:

你正試圖把一個尺寸限制到將要被方式編碼的字段。這意味着像「admin5」這樣的密碼會在域生命週期的最後作爲編碼密碼。例如,數據庫將存儲密碼爲:「$ 2a $ 10 $ dn7MyN.nsU8l05fMkL/rfek/d1odko9H4QUpiNp8USGhqx9g0R6om」。

驗證過程會將大小約束應用於未編碼的密碼(域生命週期中的驗證步驟),由於用戶鍵入的密碼在該範圍內,所以密碼會通過。但是在save()方法(域生命週期中的持久性步驟)上,pwd將在插入或更新之前進行編碼。 enconding方法將創建一個比你的約束更大的pwd,Hibernate將失敗assert()以獲得pwd的大小。

解決方案:

使用minSize屬性的約束,如果你不需要擔心MAXSIZE

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

如果您需要驗證MAXSIZE,那麼我建議你做驗證您服務或Controller層創建域實例之前。