Spring+Hibernate 中的 @Transactional

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13066017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:27:51  来源:igfitidea点击:

@Transactional in Spring+Hibernate

springhibernatetransactions

提问by Arun Kumar

I an using Spring 3.1 + Hibernate 4.xin my web application. In my DAO, i am saving User type object as following

我在我的 Web 应用程序中使用Spring 3.1 + Hibernate 4.x。在我的 DAO 中,我将用户类型对象保存如下

sessionFactory.getCurrentSession().save(user);

But getting following exception:

但得到以下异常:

org.hibernate.HibernateException: save is not valid without active transaction

I googled and found similar questionon SO, with following solution:

我用谷歌搜索并在 SO 上找到了类似的问题,解决方案如下:

   Session session=getSessionFactory().getCurrentSession();
   Transaction trans=session.beginTransaction();
   session.save(entity);
   trans.commit();

That solves the problem. But in that solution, there is lot of mess of beginning and committing the transactions manually.

这解决了问题。但是在那个解决方案中,手动开始和提交事务有很多混乱。

Can't i use sessionFactory.getCurrentSession().save(user);directly without begin/commit of transactions manually?

我不能在sessionFactory.getCurrentSession().save(user);没有手动开始/提交交易的情况下直接使用 吗?

I try to use @Transactionalon my service/dao methods too, but the problem persists.

我也尝试@Transactional在我的 service/dao 方法上使用,但问题仍然存在。

EDIT :Here is my Spring Config File:

编辑:这是我的 Spring 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:p="http://www.springframework.org/schema/p"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">


  <!-- enable the configuration of transactional behavior based on annotations -->
  <tx:annotation-driven transaction-manager="txManager"/>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="${db.driverClassName}" p:url="${db.url}"
        p:username="${db.username}" p:password="${db.password}" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.myapp.entities" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>


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

</beans>

I am using following Hibernate 4 dependencies:

我正在使用以下 Hibernate 4 依赖项:

<!-- Hibernate Dependency -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.1.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.1.1.Final</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>${cglib.version}</version>
            <scope>runtime</scope>
        </dependency>

Please help.

请帮忙。

采纳答案by Jigar Parekh

i think you are using Hibernate 4.x then why you are using hibernate 3 transaction manager in application context file?

我认为您使用的是 Hibernate 4.x 那么为什么要在应用程序上下文文件中使用 Hibernate 3 事务管理器?

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

i think it should be

我认为应该是

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

just try to use hibernate 4 transaction manager along with @Transactional attribute it should work.

只需尝试使用 hibernate 4 事务管理器以及它应该可以工作的 @Transactional 属性。

回答by hoang nguyen

Basically what needs to be done is to remove from the applicationContext.xml file the following line for Hibernate properties:

基本上需要做的是从 applicationContext.xml 文件中删除 Hibernate 属性的以下行:

<prop key="hibernate.current_session_context_class">thread</prop>

Once that is remove, Hibernate makes use of Spring for transaction management

一旦删除,Hibernate 使用 Spring 进行事务管理

Good luck to you all.

祝大家好运。

回答by Nicholas

Using your working version of the Spring XML, and the @Transactional annotated DAO class, are you defining the DAO in your Spring XML ? (Perhaps as a prototype) Because if you're not, then so far as I can see, your DAO is not going to be AOP'ed for transactional aspects. I thinkthat's the easiest way. This example is from the Spring 3 Doc, section 10.5.6 Using @Transactional.

使用您的 Spring XML 工作版本和 @Transactional 注释的 DAO 类,您是否在 Spring XML 中定义了 DAO?(也许作为原型)因为如果你不是,那么据我所知,你的 DAO 不会被 AOP 用于事务方面。我认为这是最简单的方法。这个例子是从春季3文档部分10.5.6使用@Transactional

  <!-- this is the service object that we want to make transactional -->
  <bean id="fooService" class="x.y.service.DefaultFooService"/>

  <!-- enable the configuration of transactional behavior based on annotations -->
  <tx:annotation-driven transaction-manager="txManager"/>

...where you might substitute DefaultFooServicefor your DAO.

...您可以用DefaultFooService替换您的 DAO。