使用 View-Controller-Service 架构在 Grails 中处理运行时错误

发布于 2024-08-22 02:20:26 字数 943 浏览 8 评论 0原文

我有以下情况(当然是简化的):

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 会话。当我在 RuntimeError 之后渲染 doAction.gsp 时,它会以错误结束,因为无法读取延迟加载的字段 anotherDomain (无会话)。现在你可以说“好吧,不要使用 RuntimeException”,但我需要自动事务回滚。

即使事务服务中发生 RuntimeException,如何保持 Hibernate 会话打开,以便 gsp 中的延迟加载可以正确呈现,有什么想法吗?谢谢。

I have following situation (simplified, of course):

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>

Problem happens when doSomething() throws RuntimeException. This RuntimeException rollback transaction and ends Hibernate session as well. When I render doAction.gsp after the RuntimeError, it ends with error, because lazy loaded field anotherDomain cannot be read (no session). Now you can say "ok, don't use RuntimeException", but I need the automatic transaction rollback.

Any ideas how to keep Hibernate session open even if RuntimeException happens in transactional service, so that lazy loading in gsp can render properly? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柠檬色的秋千 2024-08-29 02:20:26

如果您的 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]
  }
}

希望这适合您的需求。
参考

If your Hibernate session is destroyed during rollback and xception throwing, you can try to manually reattach it to the current Hibernate session:

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]
  }
}

Hope that's suitable for your needs.
Reference

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文