在 SkipListener 中不调用 @OnSkipInWrite [英] @OnSkipInWrite is Not Called in SkipListener
问题描述
我正在读取 csv 文件并使用 spring 批处理(读取、处理和写入)将数据插入数据库.我在 itemWriter 类中使用jpaRepository.save"将数据保存到数据库中.我试图在@OnSkipInWrite 方法中捕获跳过的项目和跳过的消息,但即使跳过数据也不会调用此方法.在 batch_step_execution 表中:read_count = 18,write_count = 10,write_skip_count = 0,roll_back_count = 8.为什么 write_skip_count 是 0?我只想知道跳过了哪个项目以及什么是特殊消息.我的步骤:
I am reading the csv file and inserting data to database using spring batch(read,process and write).I am using "jpaRepository.save" in itemWriter class to save the data into the database. And I am trying to catch the skipped item and the skipped message in @OnSkipInWrite method but this method is not called even if data are skipped. And in batch_step_execution table : read_count = 18, write_count = 10, write_skip_count = 0, roll_back_count =8. Why the write_skip_count is 0? I just want to know which item was skipped and what was the exceptional message. My step :
@Bean
public Step step() throws IOException {
return stepBuilderFactory.get("step").<Entity, Entity>chunk(1).reader(multiResourceItemReader())
.processor(processor()).writer(writer()).faultTolerant().skip(Exception.class).skipLimit(100)
.listener(new stepExecutionListener()).build();
}
这是我的监听器类.
public class StepExecutionListener{
private static final Logger LOG = Logger.getLogger(StepExecutionListener.class);
@OnSkipInRead
public void onSkipInRead(Throwable t) {
LOG.error("On Skip in Read Error : " + t.getMessage());
}
@OnSkipInWrite
public void onSkipInWrite(Entity item, Throwable t) {
LOG.error("Skipped in write due to : " + t.getMessage());
}
@OnSkipInProcess
public void onSkipInProcess(Entity item, Throwable t) {
LOG.error("Skipped in process due to: " + t.getMessage());
}
@OnWriteError
public void onWriteError(Exception exception, List<? extends Entity> items) {
LOG.error("Error on write on " + items + " : " + exception.getMessage());
}}
为什么不调用@OnSkipInWrite 和@OnWriteError?任何帮助将不胜感激.提前致谢.
Why @OnSkipInWrite and @OnWriteError is not called? Any help would be much appreciated. Thanks in advance.
推荐答案
从你分享的内容中我看不出为什么不调用跳过侦听器,但这里有一个使用你的侦听器的独立示例:
I can't see from what you shared why the skip listener is not called but here is a self-contained example using your listener:
import java.util.Arrays;
import java.util.List;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.OnSkipInProcess;
import org.springframework.batch.core.annotation.OnSkipInRead;
import org.springframework.batch.core.annotation.OnSkipInWrite;
import org.springframework.batch.core.annotation.OnWriteError;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJob {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
public ItemReader<Integer> itemReader() {
return new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
}
@Bean
public ItemWriter<Integer> itemWriter() {
return items -> {
for (Integer item : items) {
if (item.equals(3)) {
throw new Exception("No 3 here!");
}
System.out.println("item = " + item);
}
};
}
@Bean
public Step step() {
return steps.get("step")
.<Integer, Integer>chunk(5)
.reader(itemReader())
.writer(itemWriter())
.faultTolerant()
.skip(Exception.class)
.skipLimit(10)
.listener(new StepExecutionListener())
.build();
}
@Bean
public Job job() {
return jobs.get("job")
.start(step())
.build();
}
public class StepExecutionListener {
@OnSkipInRead
public void onSkipInRead(Throwable t) {
System.err.println("On Skip in Read Error : " + t.getMessage());
}
@OnSkipInWrite
public void onSkipInWrite(Integer item, Throwable t) {
System.err.println("Skipped in write due to : " + t.getMessage());
}
@OnSkipInProcess
public void onSkipInProcess(Integer item, Throwable t) {
System.err.println("Skipped in process due to: " + t.getMessage());
}
@OnWriteError
public void onWriteError(Exception exception, List<? extends Integer> items) {
System.err.println("Error on write on " + items + " : " + exception.getMessage());
}}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
StepExecution stepExecution = jobExecution.getStepExecutions().iterator().next();
System.out.println("WriteSkipCount = " + stepExecution.getWriteSkipCount());
}
}
这个例子打印:
item = 1
item = 2
Error on write on [1, 2, 3, 4, 5] : No 3 here!
item = 1
item = 2
Error on write on [3] : No 3 here!
item = 4
Skipped in write due to : No 3 here!
item = 5
item = 6
item = 7
item = 8
item = 9
item = 10
WriteSkipCount = 1
这意味着在写入时跳过项目并且 writeSkipCount
正确时调用跳过侦听器.
Which means the skip listener is called when an item is skipped on write and the writeSkipCount
is correct.
希望这会有所帮助.
这篇关于在 SkipListener 中不调用 @OnSkipInWrite的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!