Announcement Announcement Module
No announcement yet.
SpringSessionContext and long sessions? (concurrency issue?) Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • SpringSessionContext and long sessions? (concurrency issue?)

    Hi all,

    I have a JSF web application utilizing Hibernate. It runs with the OpenSessionInViewFilter, which works perfectly fine for my needs.

    In my applicationContext.xml, I have a plain DataSource, a SessionFactory and some bean definitions. Nothing special about that (really!).

        <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="java:comp/env/jdbc/foo"/>
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="packagesToScan">
            <property name="hibernateProperties">
                    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
        <tx:advice id="myAdvice" transaction-manager="transactionManager">
                <tx:method name="find*" read-only="true"/>
                <tx:method name="create" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="delete" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="save" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="*" rollback-for="Exception"/>
            <aop:pointcut id="myPointcut"
                          expression="execution(* foo.dao.*.*(..))"/>
            <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointcut"/>
        <bean id="myTransactionInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
            <property name="sessionFactory" ref="sessionFactory"/>
        <bean id="myDao" class="foo.MyDao">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean> looks something like this:

    public class MyDao {
        private SessionFactory sessionFactory;
        public MyEntity findById(Long id) {
            return (MyEntity) sessionFactory.getCurrentSession().get(MyEntity.class, id);
        public List<MyEntity> getAllMyEntities {
            Query q = sessionFactory.getCurrentSession().getNamedQuery("MyEntity.getAllMyEntities");
            return q.list();
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
    This works fine and Spring gives me Hibernate access through the same Hibernate session in each HTTP request. (Nice!)


    What makes things funny is this:

    In the same web application, I have created a context listener, which is executed by the container (Tomcat 6) on application startup. This context listener looks into Spring and creates a java.util.Timer object for each entity. I.e. something like this:

            MyDao myDao = (MyDao) WebApplicationContextUtils.getWebApplicationContext(context).getBean("myDao");
        	List<Timer> serverTimers = new ArrayList<Timer>();
        	List<MyDao> myEntities = myDao().getAllMyEntities();
        	for (MyEntity myEntity : myEntities) {
                Timer t = new Timer("Timer " + myEntity.getId());
                ServerTimerTask serverTimerTask = new ServerTimerTask(myEntity.getId());
                t.schedule(serverTimerTask, 5000, 20000);
    This creates a number of threads, which runs inside the application. What makes things go bad is that I cannot seem to have each thread bind its own Session to Hibernate.

    I have tried this inside each thread:
    Session session = SessionFactoryUtils.getSession(sessionFactory, true);
    TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
    // Do lots and lots of Hibernate/Dao stuff....
    However this doesn't seem to work, and the threads closes sessions belonging to other threads. (Seems like a concurrency issue!)

    Does anyone have a clue on how to register long Hibernate sessions in SpringSessionContext so the above code will just run inside one single Hibernate session?

    Best regards,
    Last edited by silverjam; Jul 15th, 2009, 08:22 AM.

  • #2
    It was indeed a concurrency issue.

    I missed a ThreadLocal variable to store the session in.

    This is my helper class that does the job in case other people need to do the same:

    package com.mycompany.lib.util.spring;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.orm.hibernate3.SessionFactoryUtils;
    public class HibernateSessionUtils {
        private static final Logger logger = LoggerFactory.getLogger(HibernateSessionUtils.class);
        private static ThreadLocal<Session> longSession = new ThreadLocal<Session>();
        public static Session openLongSession(SessionFactory sessionFactory) throws Exception {
            try {
                logger.trace("Opening long Hibernate session...");
                Session session = SessionFactoryUtils.getSession(sessionFactory, true);
                logger.trace("Opened long Hibernate session " + session.hashCode() + ".");
                return session;
            catch (Exception e) {
                throw new Exception("Could not open long Hibernate session.", e);
        public static void closeLongSession() {
            try {
                Session session = longSession.get();
                logger.trace("Closing long Hibernate session " + session.hashCode() + "...");
            catch (Exception e) {
                logger.warn("An error occurred while closing long Hibernate session!", e);
    The above code works with Hibernate 2.5.6.

    Best regards,