Spring Framework
  1. Spring Framework
  2. SPR-9020

Hibernate4 version of SpringSessionContext.currentSession() does not create a session if TransactionSynchronizationManager does not contain one

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 3.1 GA
    • Fix Version/s: Waiting for Triage
    • Component/s: Core
    • Labels:
    • Last commented by a User:
      true

      Description

      The Hibernate4 support of Spring 3.1 does not open and register a session in case of the method called is annotated with @Transactional(propagation = Propagation.SUPPORTS).
      In this case HibernateTransactionManager.doBegin() is never called which is the only place where hibernate session is opened. The result is, that all read operations which do not require a transaction will fail because the call to SessionFactory.currentSession() will result in an exception.

      The Hibernate3 implementation contains a fallback for this case in SessionFactoryUtils.doGetSession(...) which is missing in the corresponding Hibernate4 implementation of SpringSessionContext.currentSession().

      If the transaction propagation is changed to REQUIRES_NEW everything is working fine.

        Issue Links

          Activity

          Hide
          Matías Mirabelli added a comment -

          Hibernate does actually supports different CurrentSessionContext from outside Spring, and the session factory can be configured to use another one. There's a ManagedSessionContext that allows to bind a Session to the current thread.

          We've got the same issue migrating from Hibernate 3 to 4, and I found a workaround that works fine for us. I created a CurrentSessionContext that first delegates to SpringSessionContext and then it determines whether there's a Session bound to the current thread or not. If not, it means that there's no transaction in progress at all (or it was created with PROPAGATION_NEVER or PROPAGATION_SUPPORTS) so it opens a new Session and binds it to the current thread via ManagedSessionContext.

          In order to cleanup and close the Session at the end of the current transaction (if any), this CurrentSessionContext registers a Synchronization into TransactionSynchronizationManager, so if there's a transaction opened as PROPAGATION_NEVER or PROPAGATION_SUPPORTS the Session will be closed at the end. If there's no transaction active (which means that commit() or rollback() will never be invoked), the Session will never close.

          Here's the gist for this class:
          https://gist.github.com/seykron/4770724

          It can be configured in the hibernate.current_session_context_class property.

          Hope this help.

          Matías

          Show
          Matías Mirabelli added a comment - Hibernate does actually supports different CurrentSessionContext from outside Spring, and the session factory can be configured to use another one. There's a ManagedSessionContext that allows to bind a Session to the current thread. We've got the same issue migrating from Hibernate 3 to 4, and I found a workaround that works fine for us. I created a CurrentSessionContext that first delegates to SpringSessionContext and then it determines whether there's a Session bound to the current thread or not. If not, it means that there's no transaction in progress at all (or it was created with PROPAGATION_NEVER or PROPAGATION_SUPPORTS) so it opens a new Session and binds it to the current thread via ManagedSessionContext. In order to cleanup and close the Session at the end of the current transaction (if any), this CurrentSessionContext registers a Synchronization into TransactionSynchronizationManager, so if there's a transaction opened as PROPAGATION_NEVER or PROPAGATION_SUPPORTS the Session will be closed at the end. If there's no transaction active (which means that commit() or rollback() will never be invoked), the Session will never close. Here's the gist for this class: https://gist.github.com/seykron/4770724 It can be configured in the hibernate.current_session_context_class property. Hope this help. Matías
          Hide
          Burkhard Graves added a comment -

          Hi, any answers to Juergens question(s)?

          Migrated a project to Hibernate 4 and run into this problem today, thinking about eliminating all Propagation.SUPPORTS now...

          Cheers
          Burkhard

          Show
          Burkhard Graves added a comment - Hi, any answers to Juergens question(s)? Migrated a project to Hibernate 4 and run into this problem today, thinking about eliminating all Propagation.SUPPORTS now... Cheers Burkhard
          Hide
          RamCh added a comment - - edited

          Hi,

          We used Matias work around and working well so far.

          Thanks Matias.

          Thanks,
          Ram

          Show
          RamCh added a comment - - edited Hi, We used Matias work around and working well so far. Thanks Matias. Thanks, Ram
          Hide
          Andrew Goode added a comment - - edited

          I used a slightly modified version of Matias's workaround, and it seems to work well.

          See his comment above and my fork of his Gist for further details.

          Show
          Andrew Goode added a comment - - edited I used a slightly modified version of Matias's workaround, and it seems to work well. See his comment above and my fork of his Gist for further details.
          Hide
          Fabrício Barroso de Carvalho added a comment -

          The side effect caused by this approach is the overhead of creating and using a HibernateTransactionManager on simple queries. Not in resource consumption of the database, but in processing of the application server.

          Show
          Fabrício Barroso de Carvalho added a comment - The side effect caused by this approach is the overhead of creating and using a HibernateTransactionManager on simple queries. Not in resource consumption of the database, but in processing of the application server.

            People

            • Assignee:
              Juergen Hoeller
              Reporter:
              Reto Urfer
              Last updater:
              Fabrício Barroso de Carvalho
            • Votes:
              14 Vote for this issue
              Watchers:
              22 Start watching this issue

              Dates

              • Created:
                Updated:
                Days since last comment:
                3 weeks, 1 day ago