引入Spring Batch失败Dao-Test

时间:2018-10-25 06:00:12

标签: spring-boot spring-batch

我在Spring Boot应用程序中使用Spring Batch,如下所示。 Spring Batch和该应用程序似乎可以在该配置下正常工作。

但是,使用简单的Dao-Test的配置(不适用于Spring Batch),我得到以下异常。没有Spring Batch配置,测试运行良好。 更新:如果我配置为将自己的JobRepository与事务管理器一起使用(在类MyBatchConfigurer中),则会出现问题。

我试图为Spring Batch提供另一个事务管理器,但是我正在从一个异常到另一个异常。

org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
    at com.sun.proxy.$Proxy165.flush(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305)
    at com.sun.proxy.$Proxy165.flush(Unknown Source)
    at com.foo.dao.GenericDao.save(GenericDao.java:60)
    at com.foo.dao.GenericDao$$FastClassBySpringCGLIB$$71a0996b.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    ... 37 more

测试设置

@SpringBootTest
@RunWith(SpringRunner.class)
@EntityScan(basePackages = "com.foo.entity")
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@TestPropertySource("/mytest.properties")
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/testdata.sql")
public class MyTest {

    @Inject
    private OrderDao sut;

    @Test
    public void test_findByAnotherFieldId() {
    final Order order = // build an order ...

    sut.save(order);

    final Order result = sut.findByAnotherFieldId("valueOfOtherField");

    assertThat(result).isEqualTo(order);
  }

}

Spring Batch Job配置

@Configuration
@EnableBatchProcessing
@Import(OracleDatabaseConfig.class)
@ComponentScan(basePackageClasses = MyBatchConfigurer.class)
public class BatchJobConfig {

    // Injects...

    @Qualifier("analyseOrdersJob")
    @Bean
    public Job analyseOrdersJob() {
    return jobBuilderFactory.get("analyseOrdersJob").start(analyseOrdersStep()).build();
    }

    @Bean
    public Step analyseOrdersStep() {
    return stepBuilderFactory.get("analyseOrdersStep").<Order, String>chunk(4)
            .reader(orderItemReader) //
            .processor(orderItemProcessor) //
            .writer(orderItemWriter) //
            .build();
    }
}

Spring Batch配置

@Component
public class MyBatchConfigurer extends DefaultBatchConfigurer {

    @Inject
    private DataSource dataSource;

    @Override
    public JobRepository getJobRepository() {
        try {
          return extractJobRepository();
        } catch (final Exception e) {
          throw new BatchConfigurationException(e);
        }
    }

    private JobRepository extractJobRepository() throws Exception {
        final JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
        factory.setDataSource(dataSource);
        factory.setTransactionManager(getTransactionManager());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}

ItemReader

@Component
@StepScope
public class OrderItemReader implements ItemReader<Order> {

  @Inject
  private OrderDao orderdao;

  private int nextOrderIndex;
  private List<Order> orders;

  @PostConstruct
  public void postConstruct() {
    orders = orderdao.findAll();
  }

  @Override
  public Order read() {
    if (nextOrderIndex < orders.size()) {
      final Order order = orders.get(nextOrderIndex);
      nextOrderIndex++;
      return order;
    }

    return null;
  }

}

ItemWriter和ItemProcessor的配置类似。

0 个答案:

没有答案