2015-01-12 143 views
0

海蘭傢伙,春批,單元測試,JPA事務和Hibernate延遲加載:IllegalTransactionStateException

我想運行一個春天批處理作業,然後就導致數據的一些測試,但我需要使用Hibernate延遲加載。所以我需要一個打開的事務來保持會話活着。

但我得到這個異常:IllegalTransactionStateException:發現預綁定的JDBC連接!

我可以編寫方法直接獲取我想測試的關聯對象,但是我不想僅爲測試編寫方法,並且不會釋放hibernate的優勢。

有沒有辦法做到這一點?我已經嘗試在jobRepositoy中將validateStateTransaction設置爲false,但它不起作用(實際上它只能在像MapJobRepository這樣的內存元數據存儲庫中工作)

我在尋找幾天但。沒有什麼工作

你能幫我請感謝

我的代碼在這裏:

<bean id="jobRepository" 
    class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> 
    <property name="databaseType"> 
     <value>POSTGRES</value> 
    </property> 
    <property name="dataSource" ref="databasePool" /> 
    <property name="transactionManager" ref="transactionManager" /> 
    <property name="isolationLevelForCreate" value="ISOLATION_DEFAULT" /> 
    <property name="tablePrefix" value="#{ schema }.BATCH_" /> 
    <property name="validateTransactionState" value="false" /> 
</bean> 

@Test 
@Transactional 
public void test() { 

    /* 
    * ===================RUN JOB====================== 
    */ 
    JobParameters jobParameters = new JobParametersBuilder(); 

    int returnCode = runJob("job_name", jobParameters); 
    assertEquals("returnCode must be 0.", 0, returnCode); 

    /* 
    * ===============END JOB============================= 
    */ 

    /* 
    * ===============TEST ON DATA========================== 
    */ 
    ObjectToTest obj = objectDao.findById("1"); 

    assertNotNull(obj.getSomeCollection().get(1)); 

    /* 
    * =================END TEST================== 
    */ 

} 

這裏是個例外:

org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access. 
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:359) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:438) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:261) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 
at com.sun.proxy.$Proxy113.getLastJobExecution(Unknown Source) 
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:98) 
at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:362) 
at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:590) 
at fr.insee.harmonica.commun.batch.CommandLineJobRunnerTest.runJob(CommandLineJobRunnerTest.java:143) 
at fr.insee.harmonica.commun.batch.CommandLineJobRunnerTest.execute(CommandLineJobRunnerTest.java:420) 

我已經嘗試把測試部分,將使用@Transactional來anotated另一種方法,但後來我得到一個LazyInitializationException中......

編輯:

我使用事務管理器的org.springframework.orm.jpa.JpaTransactionManager實現。

這裏是我的Spring配置:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="myEmf" /> 
</bean> 

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

我有搜索的方式來手動打開的事務,但我沒有找到它尚未

+0

簡短的回答是,'@ Transactional'和Spring Batch的不玩好的,因爲一起Spring Batch的手動處理事務。話雖如此,你還沒有發佈你的事務管理器配置,並且Exception明確指出要使用'JpaTransactionManager'。你是? –

+0

感謝您的回答。我在下一分鐘編輯我的消息 – Philippe

+0

有人有解決方案嗎? – Philippe

回答

0

好,我找到了解決方案(沒有任何幫助,終於)。

爲此,您必須在作業結束後手動打開交易。

你可以做這樣的事情:

@Autowired 
protected PlatformTransactionManager transactionManager; 

@Test 
public void test() { 

/* 
* ===================RUN JOB====================== 
*/ 
JobParameters jobParameters = new JobParametersBuilder(); 

int returnCode = runJob("job_name", jobParameters); 
assertEquals("returnCode must be 0.", 0, returnCode); 

/* 
* ===============END JOB============================= 
*/ 

/* 
* ===============TEST ON DATA========================== 
*/ 
(new TransactionTemplate(transactionManager)).execute(new TransactionCallback() { 
     @Override 
     public Object doInTransaction(TransactionStatus status) { 

      ObjectToTest obj = objectDao.findById("1"); 

      assertNotNull(obj.getSomeCollection().get(1)); 
} 
}); 

/* 
* =================END TEST================== 
*/ 




}