2015-08-23 93 views
0

我在我的代碼中使用了兩個事務管理器。一個被標記爲主要的。完整的配置使用Spring註釋。
我嘗試使用NON-primary事務管理器進行更新的表不能將數據保存在數據庫中。如果我將同一個事務管理器標記爲主,那麼它會開始將數據插入到數據庫中。Spring JPA存儲庫不能與兩個事務管理器一起工作

在非主事務的情況下,我得到以下錯誤

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主事務管理器配置

我正在從JUnit的文件中的代碼。並且上面提到的錯誤一旦我嘗試做creditUserDetailRepository.flush();。如果我的代碼中沒有這行代碼,那麼我沒有收到任何錯誤,但是數據沒有被插入到表中。

有人可以幫我嗎?

回答

0

在您的DebitCardTransactionConfig類中,您已使用@Primary註釋標註debitEntityManagerFactory方法。該註釋意味着,只要存在多個基於類型的自動裝配候選項,就應該使用此實例。您所創建的PlatformTransactionManager就像這樣:

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

這意味着,春季應自動選擇EntityManagerFactory。因此,這兩個交易經理都被交給了借方實體經理工廠。

你應該速戰速決做什麼,是改變creditTransactionManager這樣的聲明:

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

作爲一個@Configuration類調​​用不同@Bean方法是指從範圍檢索實例,這應該工作沒有問題。不幸的是,我無法對此進行測試。請參閱旁註。

邊注意事項 下面是關於您的代碼的一些關於外觀的註釋。

  • 你的CreditCardTransactionConfigDebitCardTransactionConfig類非常類似。考慮提取一個可以消除大部分樣板的超類。
  • bean名稱取自@Bean帶註釋的方法的名稱。您無需在@Bean@Qualifier註釋中指定它。
  • 儘管共享存儲庫是一個好主意,以便任何人都可以克隆您的代碼並對其進行測試,但我無法運行您的測試,因爲它需要MySQL數據庫。考慮使用像H2這樣的內存數據庫進行實驗。
+0

非常感謝Apokralipsa。它爲我工作。也感謝您的建議。我將在我的github代碼中執行相同的操作。 我想和你一起檢查一下(如你方的註釋中的第二點),即如果我沒有使用任何限定符,那麼我的存儲庫將如何知道要使用哪個事務管理器和實體管理器? –

+0

您使用'@ EnableJpaRepositories'爲位於特定包中的實體指定實體管理器工廠和事務管理器,它仍然可以這樣工作。使用'@ Bean'註解的方法名稱,該註釋的name屬性以及'@ Qualifier'註解的value屬性在您的情況下具有相同的用途,因此您只需設置相同的名稱三次。 – Apokralipsa

相關問題