Spring和Spring-data-jpa的事务上下文

时间:2014-02-17 14:32:22

标签: java spring jpa spring-data-jpa

我正在处理导入模块,我正在从excel文件中读取,填充实体并保存它们。

现在我的麻烦在于我正在与许多实体合作,然后我用三种不同的方法分割了DB上的保存。

这是我的导入方法:

@Transactional(propagation = Propagation.REQUIRES_NEW)
private void readRowFromExcel(Row row){

    for(Row row : sheet){

        Customer customer = readCustomerFromExcel(row)
        CustomerDeatails customerDetails = readCustomerDetailsFromExcel(row)    

        customerService.save(customer,customerDetails);

        MyEntity myEntity = readMyEntityFromExcel(row);

        myEntityService.save(myEntity)

    }   


}

这是客户服务中的保存方法

@Transactional(propagation = Propagation.REQUIRED)
public void save(Customer customer, CustomerDetails customerDetails){

            customerRepository.save(customer);
            customerDatailsRepository.save(customer);

}

这是myEntity服务中的save方法:

@Transactional(propagation = Propagation.REQUIRED)
public void save(MyEntity myEntity){

    myEntityRepository.save(myEntity)

}

现在我的麻烦是,如果我在以下代码行上得到一个例外

  

MyEntity myEntity = readMyEntityFromExcel(row);

实体customer和customerDetails已经是持久性的,而我应该只在一切正常时保存

我的spring-context.xml

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${db.driverClass}" />
        <property name="url" value="${db.connectionURL}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
        p:entityManagerFactory-ref="entityManagerFactory">
        <property name="persistenceUnitName" value="myUnit" />
    </bean>

    <!-- 
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <description>Allow spring to configure hibernate specific settings</description>
    </bean>
     -->
    <bean id="eclipseLinkJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="dataSource" 
        p:persistenceUnitName="myUnit"
        p:jpaVendorAdapter-ref="eclipseLinkJpaVendorAdapter">
        <property name="jpaPropertyMap">
            <map>
                <entry key="eclipselink.cache.shared.default" value="false" />
                <entry key="eclipselink.weaving" value="false" />
            </map>
        </property>
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
    </bean>

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

我该如何解决?

1 个答案:

答案 0 :(得分:0)

解决方案很简单:在任何数据库持久化之前移动从excel读取的行:

@Transactional(propagation = Propagation.REQUIRES_NEW)
private void readRowFromExcel(Row row){

    for(Row row : sheet){
        //Reading from Excel
        Customer customer = readCustomerFromExcel(row)
        CustomerDeatails customerDetails = readCustomerDetailsFromExcel(row);
        MyEntity myEntity = readMyEntityFromExcel(row);

        //DB persisting
        customerService.save(customer,customerDetails);
        myEntityService.save(myEntity)
    }   

}