3

There are terribly many questions about this on SO, but I've tried some of them that sound correct, but I'm still getting

org.hibernate.HibernateException: No Session found for current thread

My Service layer classes are annotated as such:

   @Service
   public class MyService {
       @Autowired
       public SomeDao someDao;

       @Transactional
       public void performSomeTransaction() {/* ... */}
   }

My application context XML has the following relevant declarations:

    <context:component-scan base-package = "com.myapp.business.dao.impl" />
    <context:component-scan base-package = "com.myapp.business.services" />

    <context:annotation-config />

    <tx:annotation-driven transaction-manager = "transactionManager" />

    <!-- Hibernate -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="hibernateProperties">
            <props>
                <prop key="connection.url">jdbc:mysql://localhost:3306/bidapp</prop>
                <prop key="connection.username">bidapp</prop>
                <prop key="connection.password">pennyfss</prop>
                <prop key="connection.driver_class">com.mysql.jdbc.Driver</prop>

                <prop key="hibernate.connection.pool_size">10</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>

                <prop key="c3p0.acquireIncrement">1</prop>
                <prop key="c3p0.max_size">50</prop>
                <prop key="c3p0.max_statement">0</prop>
                <prop key="c3p0.min_size">10</prop>
                <prop key="c3p0.timeout">0</prop>
            </props>
        </property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="packagesToScan">
            <list>
                <value>com.bidapp.business.domain</value>
            </list>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/bidapp" />
        <property name="username" value="bidapp" />
        <property name="password" value="pennyfss" />
    </bean>

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

I also have my dispatcher-servlet.xml file with

    <mvc:annotation-driven />
<mvc:default-servlet-handler />

<context:component-scan base-package="com.myapp.presentation.controllers" />
<context:annotation-config />

<bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
</bean>

Why doesn't spring wrap my services with transactions?

So it appears that the issue has to do with not getting instances correctly. I have the following Shiro Security config:

    <bean id = "hibernateRealm" class = "com.bidapp.presentation.shiro.HibernateRealm" >
        <property name = "credentialsMatcher" ref = "credentialsMatcher" />
    </bean> 

    <bean id = "credentialsMatcher" class = "com.bidapp.presentation.shiro.JasyptCredentialsMatcher" />

    <bean id = "securityManager" class = "org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name = "realm" ref = "hibernateRealm" />
    </bean>

HibernateRealm is the service class with the @Transactional annotation. Shouldn't Spring be wrapping it in a proxy since it is creating it here.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724

2 Answers2

1

The most common causes of this problem are

  1. Incorrectly obtaining a service instance: for instance, instantiating it yourself rather than getting an instance from Spring.
  2. Incorrectly configuring the root and child application contexts in a Spring MVC application. I've answered quite a number of these questions here. Here are some of the more educational ones:

Spring XML file configuration hierarchy help/explanation

Declaring Spring Bean in Parent Context vs Child Context

Showing the code where you obtain and use the service instance will help define the problem.

Community
  • 1
  • 1
Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • I'm pretty sure it has to do with 1. I'm using shiro security and declare a bean service to reference in one of the security managers. Is there a workaround to this? – Sotirios Delimanolis Jan 25 '13 at 04:06
  • I was injecting a DAO into my Realm class. After your pointers, I autowired a Service class that calls the DAO. It's annotated with transactional so I get the same behavior for the cost of an extra hop. No biggie. It works. – Sotirios Delimanolis Jan 25 '13 at 04:19
0

Add the property hibernate.current_session_context_class=thread during session factory creation in hibernate-persistance.xml file it will work.

  • Can you add some more information about why this work and maybe add an example in context? – Friedrich 'Fred' Clausen Oct 16 '16 at 23:12
  • 1
    This is because once you add this property **hibernate.current_session_context_class=thread** you are saying hibernate give me a session object bounded to each thread when sessionFactory.getCurrentSession() is called. This we need to provide during creation of sessionFactory and we are using sessionFactory as the dependency in the TransactionManager Bean to manage our transactions.and spring creates transactionalProxy once thread. – vipal kaila Sep 24 '18 at 02:17