Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 3.1 + Hibernate 4.1 Propagation.Supports issue

I'm migrating my project from Spring 3.0 +hibernate 3.6.x to S3.1 + H4.1

my new code is the following

    <context:component-scan base-package="x.y.z">
</context:component-scan>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
 <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.x</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    <prop key="hibernate.hbm2ddl.auto">update</prop> 
    <prop key="hibernate.show_sql">true</prop> 
  </props>
     </property>
        <property name="annotatedClasses">
      <list>
        <value>x.y.z.entities.Student</value>        
         </list>
    </property>
  </bean>

<bean id="transactionManager" 
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>

<aop:config>
    <aop:pointcut id="daoServicePoint" 
            expression="execution(* x.y.z.StudentDao.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="daoServicePoint"/>
  </aop:config>

  <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
      <tx:method name="save*" propagation="REQUIRED"/>
       <tx:method name="update*" propagation="REQUIRED"/>
       <tx:method name="delete*" propagation="REQUIRED"/>
     <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
  </tx:advice> 

When running getStudent method marker as SUPPORTS and read only I'm getting

org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1024)

It used to be ok with Spring 3.0 and Hibernate 3.6.x now it was changed. I undestood from Spring forums that mow I need mark transaction REQUIRED if I need to use sessionFactory.getCurrentSession();

I used lower level technique in order to get maximum concurrent speed in my code. When performing operations which require several get/save/update/ queries i did it the following way:

  1. called method marked as SUPPORTS.
  2. Performed all get queries which are also marked as SUPPORTS inside first method.
  3. then started queries which marked as REQUIRED inside the same method and this is a point where my roll-able back transaction begins.

I got good performance improvement using this technique, but marking all my methods as REQUIRED destroys it.

How can work around it?

like image 805
danny.lesnik Avatar asked Apr 16 '12 21:04

danny.lesnik


1 Answers

I encountered the same issue when experimenting with Spring and Hibernate 3 / 4.

It looks like this is a known issue, which is described in the following JIRA link.

https://jira.springsource.org/browse/SPR-9020

It looks like Hibernate 4 version of SpringSessionContext does not open a new session if there is no existing transaction/session open and the called method @Transactional is configured with propagation = Propagation.SUPPORTS.

like image 159
mess Avatar answered Sep 30 '22 06:09

mess