I am writing a Spring Batch application with the following workflow:
- Read some items of type
A(using aFlatFileItemReader<A>). - Process an item, transforming it from
AtoB. - Write the processed items of type
B(using aJdbcBatchItemWriter<B>) - Eventually, I should call an external service (a RESTful API, but it could be a
SimpleMailMessageItemWriter<A>) using data from the source typeA.
How can I configure such a workflow?
So far, I have found the following workaround:
- Configuring a
CompositeItemWriter<B>which delegates to:- The actual
ItemWriter<B> - A custom
ItemWriter<B>implementation which convertsBback toAand then writes anA
- The actual
But this is a cumbersome solution because it forces me to either:
- Duplicate processing logic: from
AtoBand back again. - Sneakily hide some attributes from the source object
AinsideB, polluting the domain model.
Note: since my custom item writer for A needs to invoke an external service, I would like to perform this operation after B has been successfully written.
Here are the relevant parts of the batch configuration code.
@Bean
public Step step(StepBuilderFactory steps, ItemReader<A> reader, ItemProcessor<A, B> processor, CompositeItemWriter<B> writer) {
return steps.get("step")
.<A, B>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
public CompositeItemWriter<B> writer(JdbcBatchItemWriter<B> jdbcBatchItemWriter, CustomItemWriter<B, A> customItemWriter) {
return new CompositeItemWriterBuilder<B>()
.delegates(jdbcBatchItemWriter, customItemWriter)
.build();
}