私はSpring Batchを学んでおり、あるステップから別のステップに値を渡す必要があるサンプルプログラムを実行しています。
シナリオ:そこから個人の詳細を取得する個人テーブルがあり、いくつかの列を DTO (ステップ 1 の ItemWriter 内) に保存し、DTO からの値を where 句の別のテーブルに渡します。そこから関連する値を取得します (ステップ 2 の ItemReader 内)。最後に、これらすべての値を含む CSV を生成します。
これが私のコードです:
@Bean
public Job job() throws UnexpectedInputException, ParseException, NonTransientResourceException, Exception {
return jobBuilderFactory.get("readDBJob").incrementer(new RunIdIncrementer()).start(step1()).next(step2())
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1").<Person, Person>chunk(500000).reader(itemReader())
.writer(itemWriter()).listener(promotionListener()).build();
}
@Bean
public Step step2() throws UnexpectedInputException, ParseException, NonTransientResourceException, Exception {
return stepBuilderFactory.get("step2").<Person, Result>chunk(100)
.reader(readingObjectItemReader.cursorReader()).writer(itemWriterForStep2()).build();
}
ステップ 1 の ItemWriter:
@Bean
public ItemWriter<Person> itemWriter() {
return new ItemWriter<Person>() {
private StepExecution stepExecution;
List<personDTO> responseList = null;
@Override
public void write(List<? extends Person> items) throws Exception {
for (Person item : items) {
personDTO responseObject = new personDTO();
BeanUtils.copyProperties(item, responseObject);
if(responseObject != null && responseObject.getPersonId() != null) {
if(stepExecution.getExecutionContext().containsKey("personDtoObject")) {
responseList = (List<personDTO>) this.stepExecution.getExecutionContext().get("personDtoObject");
}
responseList.add(responseObject);
this.stepExecution.getExecutionContext().put("personDtoObject", responseList);
}
}
}
@BeforeStep
public void saveStepExecution(StepExecution stepExecution) {
this.stepExecution = stepExecution;
this.stepExecution.getExecutionContext().put("personDtoObject", new ArrayList<>());
}
}
ジョブ実行コンテキスト:
@Bean
public Object promotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys(new String[] {"personDtoObject"});
listener.setStrict(true);
return listener;
}
ステップ2 ItemReaderで値にアクセスしようとしている方法は次のとおりです
public class ReadingObjectItemReader は ItemReader を実装します {
@Autowired
DataSource dataSource;
private List<personDTO> personDtoList;
String value;
@Override
public personDetails read()
throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
return null;
}
@Bean
public JdbcCursorItemReader<personDetails> cursorReader() {
System.out.println("Values from the step 1 " + personDtoList);
....
}
@BeforeStep
public void retrieveSharedData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
personDtoList= (List<personDTO>) jobContext.get("personDtoObject");
}
}
ステップ 2 で personDtoList の値にアクセスしようとすると、null になります。ステップ 1 が完了する前に StepContext の値を検証しました。そこまではすべて問題ないように見えますが、ステップ 2 で値にアクセスしようとすると null になります。
オンラインで入手できるほとんどのリソースを見ましたが、どこが間違っているのかわかりませんでした。どんな助けでも大歓迎です。
事前に助けてくれてありがとう。