I have Spring Batch job that writes to the database (it has a step with a JpaItemWriter
). I have an integration test such as follows:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("integrationTest")
public class LoadApplicationTests {
@Autowired
private Job job;
@Autowired
private JobRepository jobRepository;
@Autowired
private JobLauncher jobLauncher;
private JobLauncherTestUtils jobLauncherTestUtils;
@Before
public void setUp() throws IOException, java.text.ParseException, Exception {
jobLauncherTestUtils = new JobLauncherTestUtils();
jobLauncherTestUtils.setJob(job);
jobRepository = new MapJobRepositoryFactoryBean(new ResourcelessTransactionManager()).getObject();
jobLauncherTestUtils.setJobRepository(jobRepository);
jobLauncherTestUtils.setJobLauncher(jobLauncher);
}
@Test
public void testJob() throws Exception {
JobParametersBuilder j = new JobParametersBuilder();
JobParameters jobParameters = j.addDate("runDate", new Date())
.addString("file", testFile.getAbsolutePath())
.addString("override", "false")
.addString("weekly", "false")
.toJobParameters();
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);
Assert.assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
}
}
When running the job in the test, it commits to the database. How can I prevent committing to the database? Normally, I could add @Transactional
to rollback the transaction after each test. However, when I add the annotation the test class, I receive:
java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).
Update
I have tried to add @Rollback
to the test class. However, the JpaItemWriter
still commits.
Here's the configuration for the transaction manager in the application code:
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public Step stepLoadFile(StepBuilderFactory stepBuilderFactory,
PlatformTransactionManager transactionManager,
ItemReader<MyClass> reader, ItemProcessor<MyClass,
MyClass> processor,
ItemWriter<MyClass> writer,
ReadFailureHandler readListenerSupport,
WriteFailureHandler writeListenerSupport) {
Step step = stepBuilderFactory.get("stepPersistFile")
.transactionManager(transactionManager)
.<MyClass, MyClass> chunk(1000)
.reader(reader)
.processor(processor)
.listener(writeListenerSupport)
.listener(readListenerSupport)
.writer(writer)
.build();
return step;
}