Grails – how to see what objets are in Hibernate session

November 5, 2012 at 19:52

Sometimes, when your Grails controllers and services relationships get complex and you do bad stuff (even without explicitly doing it! you gotta love all this magic 😆 ), Hibernate throws you lovely exceptions like the following (this is one of the most common, but there are more of them):

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

To make things even nicer, there are cases where this exceptions are thrown in code you don’t control (for example, a session flush done automatically by Hibernate when a transactional service method is invoked), so the stacktraces won’t help much (since none of the referenced classes that are yours has the line of the exception in there, remember, is autogenerated code 😀 ).

An approach for debugging this kind of errors is inspecting the session to see what objects are in there. You can do so in a service or a controller by accessing the current session. For example, the following code will search for objects in the session that are of class TypicalDomainClass:

class CoolController {
    def sessionFactory
    ...
    def fancyAction =  {
       try {
          trickyStuffWithServices()
       } catch (throwable) {
          sessionFactory.currentSession.persistenceContext.entityEntries.findAll {
             it.key instanceof TypicalDomainClass
          }.each { 
             log.debug "Found entity key: $it.key - $it.value"
          }
       }
   }
}

In the typical case, the currentSession object is of class SessionImpl, while the persistenceContext is a StatefulPersistenceContext.