Grails中的GORM和StaleObjectStateException

时间:2009-01-28 18:44:50

标签: hibernate grails gorm

我正在编写一个小的Grails应用程序,并且在运行以下相当简单的代码时,我继续获得StaleObjectStateException:s大约1/10:对“createfoo”的调用。最有可能的是我错过了使用GORM的最佳方式。

这是代码:

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()
    }
  }
}

关于GORM最佳实践的问题:

  1. “if-validate() - then-save() - else-discard()”是否有正确的方法在GORM中保留新对象?

  2. 我应该验证我要保存的所有对象()吗?即我应该在上面的代码中验证Foo-object和User-object?验证User-object会隐式检查Foo对象的状态吗?

  3. 我该怎么做才能得到StaleObjectStateException? : - )

  4. GORM / Hibernate例外:

    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 个答案:

答案 0 :(得分:2)

我注意到的一件事是你没有保存用户,即使你刚刚添加了一些foo。事实上,保存用户应该避免保存foo的需要。

您不必验证用户:它不会通过不受信任的源更改其属性,并且无论何时保存都会检查数据库级约束。

最后,像user.refresh()这样的东西最好移到你的行动之外,进入拦截器或过滤器。

答案 1 :(得分:2)

我不确定你为什么会遇到问题,但域对象上有一个merge方法。它允许您将当前对象重新附加到当前持久上下文。

我不太了解您的Foo,或者您对User对象所做的自定义,或者您正在使用的grails / java版本能够重现此内容。

我认为这与你在用户对象上做的刷新有关,导致数据库版本更新(因此不同步),但我无法确定。

另外,我认为根据对this post

的评论,在grails 1.1中,验证然后丢弃行为正在发生变化并且不太必要