Reputation: 6822
I am using an ItemListenerSupport to log errors to a database as part of a Spring Batch Job. I am validating the entries as they are processed using a ValidatingItemProcessor that implements org.springframework.validation.Validator
.
The issue is that if the item does not pass validation I am not sure how to get the validation errors into the ItemListener for logging. The afterProcess
method is called of ItemProcessListener
and has no way of receiving an exception. Is this possible?
public SimpleStepBuilder<MyItem, MyItem> simpleStepBuilder(StepBuilderFactory stepBuilderFactory,
ItemProcessor validatingItemProcessor, ItemWriter itemWriter,
MyItemErrorItemListener MyItemErrorItemListenerSupport,
MyItemSkipListener MyItemSkipListener) {
return stepBuilderFactory.get(JOB_NAME).<MyItem, MyItem>chunk(chunkSize)
.processor(validatingItemProcessor) // Calls afterProcess(MyItem src, MyItem result) with result being null
.listener((ItemProcessListener) MyItemErrorItemListenerSupport)
.writer(itemWriter)
.listener((ItemWriteListener) MyItemErrorItemListenerSupport);
}
and an example Validator:
public class MyItemValidator implements Validator {
@Override
public void validate(@NotNull Object target, Errors errors) {
MyItem myItem = (MyItem) target;
validate(target, errors);
if (CollectionUtils.isNotEmpty(errors.getAllErrors())) {
log.error("Validation Errors: [{}]", errors.getAllErrors());
}
}
}
I could throw an exception in the Validator if errors appear, but this kills the job
Upvotes: 0
Views: 973
Reputation: 31640
You should throw a ValidationException
and declare it as a skippable exception in your step. With that, you should be able to intercept invalid items with a SkipListener#skipInProcess
.
If you use SpringValidator
as delegate in ValidatingItemProcessor
, it will throw a ValidationException
that wrap a BindException
which gives you access to all validation errors for the invalid item.
Upvotes: 1