2 friday571 Friday571 于 2014.07.24 23:37 提问

spring+jpa开发,事务管理遇到奇葩问题,求码友共同探讨
最近用到spring +jpa eclipselink+ struts做开发,遇到一个无解的问题,业务层中一个用事务管理的方法中,一个受管的对象(fh)更新其一个复杂型属性(country)时居然会将country重新插入到数据库。!!!

public String updateSsss(){
Farmhouse fh = farmDao.findById(xxx);//前提1
// Farmhouse fh = new Farmhouse();//前提2
Country country = countryDao.findById(yyy);//行3
fh.setCountry(country);//关键行4
farmDao.update(fh);//行5
}

这个方法用事务管理了的,首先行5注释与否不影响结果,然后如果选择前提2的话,正常执行;如果选择前提1的话,它会将country的内容重新insert一次,导致问题的是关键行4(如果注释则不会有问题),当然,最终主键重复了插不进去,事务也回滚了。
简单说就是如果对象已存在, 更改它的关联对象就会引发插入。
小生封装了一个基本的DAO方法,其中update内部执行persist();  farmDao,countryDao都是继承基本DAO。

我附上spring事务配置代码:

<bean
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="jpaDialect" 
    class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect " /> 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
    <property name="username" value="root"/>
    <property name="password" value="111111"/>
    <property name="url" value="jdbc:mysql://111.16.253.66:3306/XXX"/>
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" />
    <property name="jpaDialect" ref="jpaDialect" /> 
    <property name="jpaVendorAdapter">
        <bean
            class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
            <property name="database" value="MYSQL" />
            <property name="showSql" value="true" />
            <property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform" /> 
        </bean>
    </property>
</bean>

<bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <property name="nestedTransactionAllowed" value="true"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
        <tx:method name="submit*" />
        <tx:method name="add*" />
        <tx:method name="delete*" />
        <tx:method name="update*" />
   </tx:attributes>
</tx:advice>

<aop:config>
  <aop:pointcut id="pointcut"  
    expression="execution(* service.impl.*.*(..))" />
  <aop:advisor advice-ref="txAdvice"
    pointcut-ref="pointcut" />
</aop:config>  

1个回答

Friday571
Friday571   2014.07.25 16:07

找到答案了,那是因为findById( id )这个函数里面,忘了将用完的EntityManager clear一下

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
JPA事务和hibernate混合事务研究<一>
混合事务用起来确实是比较麻烦的事情,我也百度了下,基本上只看见了关于jdbc事务和jpa事务(hibernate事务)混合事务的介绍,以及用法,但是就是没有看到jpa事务和hibernate混合事务的用法说明的博客或者文章。关于JPA和hibernate我就不详细介绍了,理论上来说JPA规范,hibernate是其实现,混合起来使用应该没有那么麻烦,但是混合起来是个什么样的效果呢。下
Spring事务管理所遇到的坑
记录使用Spring事务管理的坑本文的内容持续更新 一号坑:如何将Hibernate配置到Spring进行事务管理 二号坑:为何Spring的事务管理不起作用 三号坑:为何DAO的事务起作用,把DAO放到Service里就crash了 一号坑:如何将Hibernate配置到Spring进行事务管理Hibernate的配置比较简单,Spring的配置也简单,但是我第一次将它们结合在一起就不知所措了,因
Hibernate与Jpa的关系, Spring JpaTransactionManager事务管理
Jpa是一种规范,而Hibernate是它的一种实现 jpa中有Entity, Table,hibernate中也有,但是内容不同jpa中有Column,OneToMany等,Hibernate中没有,也没有替代品 jpa的注解已经是hibernate的核心,hibernate只提供了一些补充,而不是两套注解。要是这样,hibernate对jpa的支持还真够足量,我们要使用hibernat
hibernate 基于JPA的事务管理
JTA提供了跨Session的事务管理能力,这是与JDBCTransaction最大的差异。  JDBC事务由Connection管理,也就是说,事务管理实际上是在JDBC Connection中实现,事务周期限于Connection的生命周期之内,对于基于JDBC Transaction的Hibernate事务管理机制,事务管理在Session所依托的JDBC Connection
spring data jpa遇到的一些琐碎问题
jpa是几年前就已经接触过了,不过中间隔了好久没使用过,忘了不少细节上的问题。今天就来分享下在项目中遇到的一些坑吧,应该都比较基础,注意就好。 1.对象与表的映射。 全程采用注解形式,对象中的字段可以根据数据表的字段进行定义,但是在建数据表的时候要保证数据表字段都要是大写,否则在关联关系(如:一对多,多对一,多对多等)上一直会出错,说找不到对应的列。对于对象的get、set方法,可以直接采用简
Android 开发,那些奇葩的问题
开发过程中,总会遇到一些让人棘手又意外的问题。代码明明”没有问题”,怎么就是不对呢?本帖就用来记录作者在开发过程中遇到的那些意想不到的问题。 1、Intent中携带的数据错位了 使用Intent携带数据再平常不过了,谁会想到这都会出问题。简单描述如下: Intent中携带的数据本来是 "key1":"value1" "key2":"value2" "key3":"value3"
jpa、mybatis事务混合测试记录
环境 本次测试代码基于之前到《 springmvc、jpa(hibernate)、mybatis组合框架搭建(三)》搭建的环境。 配置文件调整 鉴于以前的spring-mybatis.xml和spring-jpa.xml中都有transaction相关的配置。datasource是配在spring-mybatis.xml中,但是却会被mybatis和jpa共同使用。 我们这次将新
Spring Boot(二):整合 JPA 及 事务控制
一、什么是JPA? JPA(Java Persistence API) Java 持久层API,是JDK5.0注解或XML描述 对象-关系表的映射关系,并将运行期内的实体对象持久化到数据库中。 JPA的总体思想和现有Hibernate、TopLink、Jdo等ORM框架大体一致,总的来说,JPA 包括以下3方面的技术: 1、ORM映射元数据 JPA支持XML和JDK5.0注解两种元数据的形
程序员奇葩面试的奇葩问题
作为一个程序猿,去年我去了一家非常大的互联网公司面试,我相信大家对于大公司的面试都应该有一定的了解,他们喜欢面试一些算法和一些奇葩的问题,算法我猜到了,但是对于那个奇葩问题我还真没弄懂。最后可算明白了。 面试题如下: 面试官:我给你出一道非常简单的题,也不不算是技术题,是这样的,你给我在玻璃板上画上一幅画,场景是这样的,有一颗树,树上有三个苹果,树下面有一片草,非常简单,好了你赶紧画吧
SpringBoot中JPA事务失效的问题
在SpringBoot中使用jpa,表是通过对应的实体直接建立,默认情况下,表的引擎engine=MyISAM性能更好,但不提供事务支持,如果需要使用事务,需要将JPA建表的默认引擎修改为:InNoDB,直接修改配置文件,如下: # application.xml spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoD...