我在使用 Spring Batch 多线程时遇到错误。错误:无法读取字段“item”,因为“x”为空 当我不使用多线程时,我不会收到任何错误。 我不知道是什么原因导致了这个问题
工作班
@Bean("multiThreadTaskExecutor")
public SimpleAsyncTaskExecutor getTaskExecutorCreation() {
SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
executor.setThreadNamePrefix("Batch-MultiThread");
return executor;
}
@Autowired
@Qualifier("multiThreadTaskExecutor")
private TaskExecutor multiThreadTaskExecutorStepCreation;
public Job createJob(String batchCode, String jobName, int chunkSize, ListItemReader<I> reader, ItemProcessor<O, O> itemProcessor) {
Step stepCreation = stepBuilderFactory.get(StepName.STEPCREATION.name).listener(new CustomStepExecutionListener(batchCode, batchService)).<I, I>chunk(100).reader(reader) .writer(createWriter).taskExecutor(multiThreadTaskExecutorStepCreation).throttleLimit(3)
.build();
return jobBuilderFactory.get(jobName).preventRestart()
.incrementer(new RunIdIncrementer())
.listener(new CustomJobExecutionListener(batchService))
.start(stepCreation)
.build();
}
@StepScope
@Bean(name = "batchExecutionDetailCreateWriter")
public ItemWriter<I> batchExecutionDetailCreateWriter(@Value("#{stepExecution}") StepExecution stepExecution) {
List<DetailDto> detailList = new ArrayList<>();
ItemWriter<I> writer = list -> {
List<DetailDto> dtoList = new ArrayList<>();
for (I item : list) {
DetailDto dto = new DetailDto(batchExecutionId, item, null);
dtoList.add(dto);
}
detailList.addAll(dtoList);
};
return writer;
}
错误:
2023-11-20 22:59:01.214 TRACE [Payment Batch,,] username=[test] 168594 --- [ Batch-4] o.s.j.c.StatementCreatorUtils : Setting SQL statement parameter value: column index 5, parameter value [java.lang.NullPointerException: Cannot read field "item" because "x" is null
at java.base/java.util.LinkedList.unlink(LinkedList.java:215)
at java.base/java.util.LinkedList.remove(LinkedList.java:530)
at org.springframework.batch.item.support.ListItemReader.read(ListItemReader.java:52)
at org.springframework.batch.item.support.ListItemReader$$FastClassBySpringCGLIB$$d4c638f3.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:118)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:71)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransacti], value class [java.lang.String], SQL type 12
如何解决这个问题?
我建议您检查两件事:
检查ListItemReader读取到的数据不为空。
确保ListItemReader是线程安全的