2009-01-28 43 views
7

我正在編寫一個小的Grails應用程序,並且在運行以下相當簡單的代碼時,我一直在獲取StaleObjectStateException:s約爲「createfoo」調用次數的1/10:th。我很可能錯過了使用GORM的最佳方式。Grails中的GORM和StaleObjectStateException

這是代碼:

def viewfoo = { 
    session.user.refresh() 
    // ... 
} 

def createfoo = { 
    session.user.refresh() 
    var user = session.user 
    if (param["name"]) { 
    var newFoo = new Foo() 
    newFoo.name = param["name"] 
    if (newFoo.validate()) { 
     newFoo.save() 
     if (user.validate()) { 
     user.addToFoos(newFoo) 
     } else { 
     user.discard() 
     } 
    } else { 
     newFoo.discard() 
    } 
    } 
} 

我的問題關於格姆最佳實踐:

  1. 就是「如果-的validate() - 然後保存() - 否則放棄() 「在GORM中堅持一個新對象的正確方法是什麼?

  2. 我應該驗證我要保存的所有對象()嗎?即我應該在上面的代碼中驗證Foo對象和用戶對象嗎?將驗證用戶對象隱式檢查Foo對象的狀態?

  3. 我做了什麼值得StaleObjectStateException? :-)

的格姆/休眠例外:

 
Caused by: Object of class [Foo] with identifier [15]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Foo#15] 

回答

2

我不完全確定你爲什麼遇到問題,但在域對象上有一個merge方法。它使您可以將當前對象重新附加到當前的持久性上下文。

我不太瞭解你的Foo,或者你對User對象所做的定製,或者你使用的grails/java版本能夠重現這一點。

我在想這與刷新你正在做的用戶對象導致數據庫版本更新(並因此不同步),但我不能確定。

此外,我相信,驗證,然後丟棄行爲正在改變,並且在grails 1.1中基於this post

2

有一件事我注意到的是,你不保存用戶,即使你只是增加了一些富吧。事實上,保存用戶應該避免保存foo的需要。

您不必驗證用戶:它的屬性沒有被不受信任的源更改,並且無論何時都保存數據庫級別的約束。

最後,像user.refresh()這樣的東西最好移動到你的動作之外並進入攔截器或過濾器。