2011-12-26 61 views
5

我有兩個類:如何恢復`發生異常後不刷新會話'錯誤?

用戶

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。

在此先感謝。

回答

10

你得到這個錯誤的原因是當執行語句Role.findBy靜態方法時,Hibernate(由grails GORM使用)檢查是否需要「autoFlush」。由於存在新的臨時角色對象,因此Hibernate會嘗試自動刷新會話。但是,在這一點上,新的用戶對象存在,這些對象尚未與角色關聯(在用戶域中不能爲空)。因此,在刷新時,用戶對象不會通過驗證,因此具有如例外中所述的空id。

解決此問題的方法是在啓動創建/更新相同類型的實體之前,使所有DB讀取調用(例如findBy方法)

另一個選項(雖然不是很好的一個)是設置會話刷新模式手冊。

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

    } 
0

如果你正在使用Spring Security的核心,如果添加約束size或者創建自定義validator來檢查,如果「密碼」等於「確認密碼」發生同樣的錯誤。解決方法是在這些情況下使用命令對象。這個案例解決here

一般來說,如果某些字段爲空,但它不應該爲空,而是通過約束(通常是因爲代碼中有一些錯誤),則可能發生此錯誤。該數據庫具有非空規則,因此不會創建該條目。那麼Grails將顯示那個醜陋的錯誤。

相關問題