2009-01-28 54 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()这样的东西最好移动到你的动作之外并进入拦截器或过滤器。

相关问题