Обработка RuntimeError в Grails с использованием архитектуры View-Controller-Service - PullRequest
0 голосов
/ 12 февраля 2010

У меня следующая ситуация (упрощенно, конечно):

MyDomain.groovy:
class MyDomain {
  MyAnotherDomain anotherDomain   // lazy loaded
}

MyService.groovy:
class MyService {

 boolean transactional = true

 def doSomething(id) {
   // ... some code...
 }
}

MYController.groovy:
class MyController {
  def myService
  def doAction = {
    MyDomain aaa = ...GET_IT_FROM_SOMEWHERE...
    try {
      myService.doSomething(id)
    } catch (RuntimeError e) {
      flash.message = 'sorry.guy.your.transaction.was.rollbacked'
    }
    [myData: aaa]
  }
}

doAction.gsp:
<html>
<body>
${myData.anotherDomain}
</body>
</html>

Проблема возникает, когда doSomething () генерирует исключение RuntimeException. Эта транзакция отката RuntimeException также завершает сеанс Hibernate. Когда я отображаю doAction.gsp после RuntimeError, он заканчивается ошибкой, потому что лениво загруженное поле anotherDomain не может быть прочитано (без сеанса). Теперь вы можете сказать «хорошо, не используйте RuntimeException», но мне нужен автоматический откат транзакции.

Есть идеи, как сохранить сеанс Hibernate открытым, даже если RuntimeException происходит в транзакционном сервисе, чтобы ленивая загрузка в gsp могла правильно отображаться? Спасибо.

1 Ответ

2 голосов
/ 03 марта 2010

Если ваш сеанс Hibernate разрушен во время отката и выброса xception, вы можете попытаться вручную присоединить его к текущему сеансу Hibernate:

MyController.groovy:

class MyController {
  def myService
  def doAction = {
    MyDomain aaa = ...GET_IT_FROM_SOMEWHERE...
    try {
      myService.doSomething(id)
    } catch (RuntimeError e) {
      flash.message = 'sorry.guy.your.transaction.was.rollbacked'
      if(!aaa.isAttached()) {
        aaa.attach()
      }
    }
    [myData: aaa]
  }
}

Надеюсь, что это подходит для ваших нужд. Ссылки

...