Updating a processed item in Spring Batch

911 Views Asked by At

I have a Spring Batch app that uses ItemProcessor to process items.

@Component
@StepScope
public class MemberProcessor<T> implements ItemProcessor<T, Member> {

    @Override
    public Member process(T t) throws Exception {
        return processMember((UnprocessedMember) t);
    }
}

@Component
@StepScope
public class MemberWriter implements ItemWriter<Member> {

    @Override
    public void write(List<? extends Member> members) throws Exception {
        //store the members in db
        saveToDb(members);
    }
}

I want to know if it is possible to update an item after it's been processed so that when it gets to ItemWriter, it's updated. For example, I process one item, and then I process another one that may need to edit a property of the previous item. As the previous item has not reached the Writer, I can't do the update on the database and the first item gets written without the update

1

There are 1 best solutions below

0
On

Spring Batch provides ItemProcesListener for the processing of an item before items processed by the writer. Implementations of this interface will be notified before and after an item is passed to the ItemProcessor and in the event of any exceptions thrown by the processor. So basically you need to create a custom item process listener implementing ItemProcesListener and register with the processor setp task. Example:

public class MyCustomItemProcessListener implements ItemProcessListener<T, R> {

    @Override
    public void beforeProcess(T item) {
        System.out.println("MyCustomItemProcessListener - beforeProcess");
    }

    @Override
    public void afterProcess(T item, R result) {
        System.out.println("MyCustomItemProcessListener - afterProcess");
        // Apply your custom logic to act on the object before write
    }

    @Override
    public void onProcessError(T item, Exception e) {
        System.out.println("MyCustomItemProcessListener - onProcessError");
    }
}

Now you can add the listener to your step. This depends on your Step definitions and configurations. But essentially something like the below.

StepBuilderFactory.get("Stepx")
...
.processor(someProcessor).listener(new MyCustomItemProcessListener())
...

Or

steps.get("stepx")
            .tasklet(new MyProcessorTask())
            .listener(new MyCustomItemProcessListener())
            .build();