为什么Spring的事务管理不能使用此配置?

时间:2013-01-25 03:22:18

标签: java spring hibernate spring-transactions

在SO上有很多关于此的问题,但我已经尝试了其中一些听起来不错的问题,但我还是得到了

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

我的服务层类注释如下:

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

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

我的应用程序上下文XML具有以下相关声明:

    <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>

我还有dispatcher-servlet.xml个文件

    <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>

为什么不用事务弹出我的服务?

因此,问题似乎与未正确获取实例有关。我有以下Shiro Security配置:

    <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是具有@Transactional注释的服务类。 Spring不应该将它包装在代理中,因为它在这里创建它。

2 个答案:

答案 0 :(得分:1)

此问题的最常见原因是

  1. 错误地获取服务实例:例如,自己实例化而不是从Spring获取实例。
  2. 在Spring MVC应用程序中错误地配置根和子应用程序上下文。我在这里回答了很多这样的问题。以下是一些更具教育意义的内容:
  3. Spring XML file configuration hierarchy help/explanation

    Declaring Spring Bean in Parent Context vs Child Context

    显示您获取和使用服务实例的代码将有助于定义问题。

答案 1 :(得分:0)

在会话工厂创建期间,在hibernate-persistance.xml文件中添加属性hibernate.current_session_context_class = thread,它将起作用。