views:

274

answers:

1

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.

+2  A: 

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

air_blob
unfortunately this is the only solution that I found too.
Pavel P