开发者社区> 问答> 正文

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>  

展开
收起
小旋风柴进 2016-03-03 11:29:34 3065 0
1 条回答
写回答
取消 提交回答
  • 是因为findById( id )这个函数里面,忘了将用完的EntityManager clear一下

    2019-07-17 18:51:08
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载

相关实验场景

更多