Question

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.

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top