craigmiller160
craigmiller160

Reputation: 6263

Hibernate & Thread Safety: Is an injected SessionFactory thread safe?

So, I'm using a Hibernate DAO with Spring. My DAO is going to be constructed by the ApplicationContext IOC container, and the SessionFactory is going to be injected by the container (LocalSessionFactoryBean).

Now, this DAO is going to be a singleton, used for all CRUD operations in my program, with a pool of database connections behind it. My concern is about the thread safety of the sessionFactory field.

My understanding of thread safety is that all state fields need to be guarded in a multi-threaded environment. Now, the use of this class will be that Spring will set the SessionFactory upon bean creation, and that factory won't be changed after that. This means that TECHNICALLY it could function safely in a multi-threaded environment, but I feel that's a very risky practice, to just operate on the assumption that the setter method won't be called again.

The thing is, synchronizing the SessionFactory would require all calls to it to be synchronized as well. So the insertPortfolio() method I put in below would need to be synchronized as well, which defeats the purpose of having a pool of available connections to the database, since access will be limited to one thread at a time.

I guess the best solution I can think of is to change this from setter injection to constructor injection, and make the SessionFactory field final. But I'm trying to understand the broader issues at stake here, so I can make good multi-threaded safety decisions with spring in the future.

private SessionFactory sessionFactory;

public HibernatePortfolioDao() {}

public void setSessionFactory(SessionFactory sessionFactory){
    this.sessionFactory = sessionFactory;
}

@Override
public void insertPortfolio(PortfolioModel portfolioModel) {
    sessionFactory.getCurrentSession().save(portfolioModel);
}

Upvotes: 3

Views: 1803

Answers (4)

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153720

The SessionFactory is thread-safe, and it's initialized only once during application bootstrap. Because you're using Spring, the SessionFactory is represented by LocalSessionFactoryBean.

What you were concerned was properly the Seesion returned by sessionFactory.getCurrentSession() which is bound to the current Thread by HibernateTransactionManager.

Upvotes: 6

padippist
padippist

Reputation: 1206

SessionFactory in hibernate is thread safe. You should implement it using a singleton mechanism because it resource draining.

Upvotes: 0

Atul
Atul

Reputation: 2711

The frameworks implementing SessionFactory have to make their SessionFactories thread safe and concurrent. If you are using a good framework, then the sessionFactory being injected can be considered thread safe. You don't have to worry about a session factory implementation because the documentations asks the implementations be thread safe. The sessions you get from a session factory are per session/transactions and don't have to be thread safe.

Upvotes: 0

Ann Addicks
Ann Addicks

Reputation: 925

A good place to start looking is at the Class itself: http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/SessionFactory.html

The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.

This allows it to be shared by multiple threads without worrying about synchronizing it.

Upvotes: 0

Related Questions