IcedDante
IcedDante

Reputation: 6822

Spring Batch ValidatingItemProcessor with ItemListener

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

Answers (1)

Mahmoud Ben Hassine
Mahmoud Ben Hassine

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

Related Questions