Spring JPA存储库不能与两个事务管理器一起使用

时间:2015-08-23 07:54:10

标签: spring jpa

我在代码中使用了两个事务管理器。一个标记为主要。完整配置使用Spring注释 我尝试使用NON主要事务管理器更新的表无法在数据库中保存数据。如果我将同一个事务管理器标记为primary,则它开始将数据插入数据库。

如果是非主要交易,我将收到以下错误

org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:157)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy39.flush(Unknown Source)
    at com.ashish.business.CreditCardManagementImpl.addCreditCardUser(CreditCardManagementImpl.java:44)
    at com.ashish.business.CreditCardManagementImpl.addCrCardCustomerData(CreditCardManagementImpl.java:30)

我的代码出现在以下位置 https://github.com/ashismo/repositoryForMyBlog/tree/master/spring/SpringJPARepoDistributedTransaction

在我的代码中, com.ashish.appConfig 包有三个名为 AppConfig.java,CreditCardTransactionConfig.java和DebitCardTransactionConfig.java 的类。其中 AppConfig 包含其他两个类, CreditCardTransactionConfig.java 具有 NON 主要事务管理器配置

我从junit文件运行此代码。一旦我尝试 creditUserDetailRepository.flush();就会出现上述错误。如果我的代码中没有这一行,那么我没有收到任何错误,但数据没有插入表中。

有人能帮助我吗?

1 个答案:

答案 0 :(得分:0)

DebitCardTransactionConfig课程中,您已使用debitEntityManagerFactory注释注释了@Primary方法。该注释意味着,只要有多个基于类型的自动装配候选者,就应该使用该实例。您正在创建PlatformTransactionManager,如下所示:

@Bean(name="creditTransactionManager")
@Qualifier("creditTransactionManager")
public PlatformTransactionManager creditTransactionManager(
            EntityManagerFactory emf) {
    //...
}

这意味着Spring应该自动选择EntityManagerFactory。因此,两个交易经理都交给了借方实体经理工厂。

你应该做些什么来快速修复,就是像这样更改creditTransactionManager的声明:

@Bean(name="creditTransactionManager")
@Qualifier("creditTransactionManager")
//  @Primary
public PlatformTransactionManager creditTransactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(creditEntityManagerFactory().getObject());
    return transactionManager;
}

@Bean类中调用不同的@Configuration方法意味着从范围中检索实例,这应该没有问题。不幸的是,我无法测试这一点。见旁注。

侧面说明 以下是有关您的代码的一些非正式说明。

  • 您的CreditCardTransactionConfigDebitCardTransactionConfig课程非常类似。考虑提取一个可以消除大部分样板的超类。
  • bean名称取自@Bean带注释方法的名称。您无需在@Bean@Qualifier注释中指定它。
  • 虽然最好共享一个存储库,以便任何人都可以克隆你的代码并对其进行测试,但我无法运行你的测试,因为它需要一个MySQL数据库。考虑使用像H2这样的内存数据库进行实验。