【问题标题】:Spring batch, Unit test, JPA Transaction and Hibernate Lazy loading : IllegalTransactionStateExceptionSpring 批处理、单元测试、JPA 事务和 Hibernate 延迟加载:IllegalTransactionStateException
【发布时间】:2015-01-12 18:01:05
【问题描述】:

大家好,

我想运行一个 spring 批处理作业,然后对结果数据进行一些测试,但我需要使用休眠延迟加载。所以我需要一个打开的事务来保持会话处于活动状态。

但我得到了这个异常:IllegalTransactionStateException : Pre-bound JDBC Connection found!

我可以编写方法来直接获取我想要测试的关联对象,但我不想只为测试而编写方法并失去 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 注释的方法中,但随后我得到了一个 LazyInitializationException...

编辑:

我将 org.springframework.orm.jpa.JpaTransactionManager 实现用于事务管理器。

这是我的弹簧配置:

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

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

我已经搜索过手动开启交易的方式,但还没有找到

【问题讨论】:

  • 简短的回答是@Transactional 和 Spring Batch 不能很好地配合使用,因为 Spring Batch 手动处理事务。话虽如此,您还没有发布您的事务管理器配置,并且异常清楚地指出使用JpaTransactionManager。你是吗?
  • 感谢您的回答。我会在下一分钟编辑我的消息
  • 有人有解决办法吗?
  • 当你删除@Transactional时会发生什么?
  • 我得到一个 LazyInitializationException 因为没有会话打开,所以延迟加载不起作用

标签: java hibernate jpa spring-batch transactionmanager


【解决方案1】:

好的,我找到了解决方案(最终没有任何帮助)。

为此,您必须在工作结束后手动打开交易。

你可以这样做:

@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==================
 */




}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2011-05-11
    • 2016-12-21
    • 2019-04-28
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    相关资源
    最近更新 更多