GORM в Grails и StaleObjectStateException - PullRequest
       22

GORM в Grails и StaleObjectStateException

7 голосов
/ 28 января 2009

Я пишу небольшое приложение 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-объект и User-объект в приведенном выше коде? Будет ли проверка User-объекта неявно проверять состояние Foo-объекта?

  3. Что я сделал, чтобы заслужить исключение StaleObjectStateException? : -)

Исключение 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 ]

2 голосов
/ 29 января 2009

Я не совсем уверен, почему вы сталкиваетесь с проблемами, но есть метод merge для доменных объектов. Это позволяет вам повторно присоединить текущий объект к текущему постоянному контексту.

Я недостаточно знаю, какой у вас Foo или какие настройки вы сделали для объекта User, или версию grails / java, которую вы используете, чтобы иметь возможность воспроизвести это.

Я думаю, что это как-то связано с обновлением, которое вы выполняете для объекта пользователя, в результате чего версия базы данных обновляется (и, следовательно, не синхронизируется), но я не могу быть в этом уверен.

Кроме того, я считаю, что поведение validate затем discard меняется и менее необходимо в grails 1.1, основываясь на комментариях к этой записи

2 голосов
/ 28 января 2009

Одна вещь, которую я заметил, это то, что вы не сохраняете пользователя, даже если вы только что добавили в него немного foo. Фактически, сохранение пользователя должно избавить от необходимости сохранять foo.

Вам не нужно проверять пользователя: его свойства не изменяются ненадежным источником, а ограничения на уровне базы данных проверяются в любом случае при каждом сохранении.

И наконец, такие вещи, как user.refresh (), лучше перемещать за пределы ваших действий в перехватчик или фильтр.

...