Java – why does each thread in my application use a different hibernate session?
I have a web application using hibernate. For some reason, each thread (httprequest or other threads related to queuing) uses a different session
public class HibernateSessionFactory { private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new AnnotationConfiguration(); private static org.hibernate.SessionFactory sessionFactory; static { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) {} } private HibernateSessionFactory() {} public static Session getSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session == null || !session.isopen()) { if (sessionFactory == null) { rebuildSessionFactory();//This method basically does what the static init block does } session = (sessionFactory != null) ? sessionFactory.openSession(): null; threadLocal.set(session); } return session; } //More non relevant methods here.
From the beginning of my test, it seems that ThreadLocal members do initialize only once when the JVM loads the class for the first time, but for some reason, when different threads access the getsession () method, they use different sessions When a thread first accesses this class (session) ThreadLocal get(); Null will be returned, but as expected, all other access requests will generate the same session I'm not sure how this happened, because the ThreadLocal variable is final and the method ThreadLocal Set (session) is only used in the above context (I'm 99.9% sure to have non empty sessions because I'll encounter NullPointerException in different parts of my application)
I'm not sure if this is relevant, but these are my hibernate cfg. Main parts of XML file:
<hibernate-configuration> <session-factory> <property name="connection.url">someURL</property> <property name="connection.driver_class"> com.microsoft.sqlserver.jdbc.sqlServerDriver</property> <property name="dialect">org.hibernate.dialect.sqlServerDialect</property> <property name="hibernate.connection.isolation">1</property> <property name="hibernate.connection.username">User</property> <property name="hibernate.connection.password">Password</property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">false</property> <property name="current_session_context_class">thread</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.cache.use_second_level_cache">false</property> <property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Mapping files -->
I appreciate any help. Of course, if anyone has any questions, I will be happy to clarify ether
Solution
Do you know the purpose of ThreadLocal?
Start with the docs:
You are getting different hibernate sessions exactly for each thread, because that's what your code needs to do
Now, we can't comment on whether this is a good thing - although it makes sense in many cases After all, you don't want two threads to share the same session and interact with each other's transactions, do you?