3

I'm using Spring 4.2.1 and Hiberante 5 and now trying to understand how spring initializes the Session declared in the Spring Beans Definition as follows:

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <!-- properties -->
</bean>

I found that so called org.springframework.orm.hibernate5.LocalSessionFactoryBean implements FactoryBean<SessionFactory>. Taking this into account it's clear why we define the SessionFactory definition to be injected with the class org.springframework.orm.hibernate5.LocalSessionFactoryBean but end up with the instance of SessionFactory. Now, what I was confused by is the method getCurrentSession:

public Session  getCurrentSession() throws HibernateException {
    if ( currentSessionContext == null ) {
        throw new HibernateException( "No CurrentSessionContext configured!" );
    }
    return currentSessionContext.currentSession();
}

which delegates the actual session creation to the SpringSessionContext and in my case it's being retrieved by this piece of code:

SessionHolder sessionHolder = (SessionHolder) value;
Session session = sessionHolder.getSession();

But the session is actually an instance of org.hibernate.internal.SessionImpl the direct base class org.hibernate.internal.AbstractSessionImpl of which itself has the property protected transient SessionFactoryImpl factory.

So, the SessionFactory has the CurrentSessionContext property which in my case holds SessionHolder which in turn holds the actual Session instance. But the SessionImpl again has a property of the type SessionFactory.

I cannot understand the circular. Couldn't you explain it a bit.

Bacteria
  • 8,406
  • 10
  • 50
  • 67
St.Antario
  • 26,175
  • 41
  • 130
  • 318

1 Answers1

1

Well, Spring implementation of CurrentSessionContext does not hold SessionHolder, instead Sessionholder is retrieved every time that currentSession method is invoked. See this:

Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
...
SessionHolder sessionHolder = (SessionHolder) value;

So, in your case there are injected some implementations, but it can be another one in case of different configuration.

I think the main purpose of that design is to have a good separation of concerns. The main purpose of the SessionContext is to relate transaction manager and session holder to provide you a well configured session depending on transaction configuration.

There are other implementations of CurrentSessionContext, I believe hibernate has at least three implementations, so the scenario that you have described depends on the spring configuration that injects such classes.

As javaDoc states:

CurrentSessionContext implementation can also be specified in custom SessionFactory setup through the "hibernate.current_session_context_class"

malaguna
  • 4,183
  • 1
  • 17
  • 33
  • Yes, indeed, you're absolutely right. I figured out that `TransactionSynchronizationManager` has a `private static ThreaLocal` field called `resources`. And the actual binding the `SessionHolder` is being performed by wrapping the Session intance into the holder as `new SessionHolder(session)` and then binding with the key `sessionFactory`. But it's still a little hard to understand how the circularityness provides the separation of concerns.... – St.Antario Oct 25 '15 at 08:21