简体   繁体   English

Grails中的GORM和StaleObjectStateException

[英]GORM in Grails and StaleObjectStateException

I'm writing a small Grails app, and I keep on getting StaleObjectStateException:s for about 1/10:th of the calls to "createfoo" when running the following rather simple code. 我正在编写一个小的Grails应用程序,并且在运行以下相当简单的代码时,我继续获得StaleObjectStateException:s大约1/10:对“createfoo”的调用。 Most probably I'm missing out on the best way to use GORM. 最有可能的是我错过了使用GORM的最佳方式。

This is the code: 这是代码:

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

My questions regarding GORM best practices: 关于GORM最佳实践的问题:

  1. Is the "if-validate()-then-save()-else-discard()" the correct way do to persist a new object in GORM? “if-validate() - then-save() - else-discard()”是否正确地在GORM中保留新对象?

  2. Should I validate all objects that I'm about to save()? 我应该验证我要保存的所有对象()吗? Ie should I validate both the Foo-object and the User-object in the above code? 即我应该在上面的代码中验证Foo-object和User-object? Will validating the User-object implicitly check the status of the Foo-object? 验证User-object会隐式检查Foo对象的状态吗?

  3. What did I do to deserve the StaleObjectStateException? 我该怎么做才能得到StaleObjectStateException? :-) :-)

The GORM/Hibernate exception: 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]

One thing I notice is that you're not saving user, even though you've just added some foo to it. 我注意到的一件事是你没有保存用户,即使你刚刚添加了一些foo。 In fact, saving user should obviate the need to save foo. 实际上,保存用户应该避免保存foo的需要。

You don't have to validate user: it's not having its properties changed by an untrusted source, and the database-level constraints are checked anyway whenever you save. 您不必验证用户:它不会通过不受信任的源更改其属性,并且无论何时保存,都会检查数据库级约束。

Lastly, things like user.refresh() are better moved outside your actions and into an interceptor or a filter. 最后,像user.refresh()这样的东西最好移到你的动作之外,进入拦截器或过滤器。

I'm not exactly sure why you're hitting issues, but there is a merge method on domain objects. 我不确定你为什么会遇到问题,但是在域对象上有一个合并方法。 It lets you reattach the current object to the current persistent context. 它允许您将当前对象重新附加到当前持久上下文。

I don't know enough about what your Foo, or what customizations you've done to the User object, or the version of grails/java you're using to be able to reproduce this. 我不太了解您的Foo,或者您对User对象所做的自定义,或者您正在使用的grails / java版本能够重现这一点。

I'm thinking it has something to do with the refreshing you're doing on the user object which is causing the database version to get updated (and thus out of sync), but I can't be sure. 我认为它与你在用户对象上做的刷新有关,导致数据库版本更新(因此不同步),但我不能确定。

Also, I believe that the validate then discard behavior is changing and less necessary in grails 1.1 based on the comments on this post 另外,我认为根据对这篇文章的评论,验证然后丢弃行为正在改变,并且在grails 1.1中不太必要

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM