Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Batch - Counting Processed Rows

So I am creating a Spring Batch job for reading a CSV file and for certain rows which contain incomplete data; it checks, outputs to the log that the row is incomplete, and skips. It works great except at the end of the job I want it to log how many rows it found that were incomplete. Just something simple like "X incomplete rows were found".

I've Googled and searched around for a solution but not found anything really.

Any help is appreciated and any more info needed just ask.

like image 967
dogfight Avatar asked Sep 11 '13 14:09

dogfight


People also ask

What is filter count in Spring Batch?

If an item was skipped for example, it would have been read, but not filtered or written. For the record, the filter count is the count of times the ItemProcessor returned null which is different than an item being skipped due to a skippable exception being thrown.

What is chunking in Spring Batch?

Spring Batch uses a 'Chunk-oriented' processing style within its most common implementation. Chunk oriented processing refers to reading the data one at a time and creating 'chunks' that are written out within a transaction boundary.

What is ExecutionContext in Spring Batch?

An ExecutionContext is a set of key-value pairs containing information that is scoped to either StepExecution or JobExecution . Spring Batch persists the ExecutionContext , which helps in cases where you want to restart a batch run (e.g., when a fatal error has occurred, etc.).

What is ItemWriter in Spring Batch?

ItemWriter. It is the element of the step of a batch process which writes data. An ItemWriter writes one item a time. Spring Batch provides an Interface ItemWriter. All the writers implement this interface.


2 Answers

Spring Batch itself keeps track of how many records it reads, writes, processes and how many it skips (for each of those numbers). That information is stored in the StepExecution. The StepExecution can be accessed from a StepExecutionListener. In this case an implementation of the afterStep method will suffice.

public class SkippedItemStepExecutionListener extends StepExecutionListenerSupport {

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        int skipped = stepExecution.getSkipCount(); // Total for read+write+process
        // Log it to somewhere.        
        return null;
    }
}

How to add it to your job/step is explained in the reference guide

Links

  1. StepExecution javadoc
  2. StepExecutionListener javadoc
  3. Listener Configuration Reference
like image 99
M. Deinum Avatar answered Sep 27 '22 19:09

M. Deinum


Manage to solve this, here's how I did it:

In the ItemProcessor I added an attribute and a method for getting access to the ExecutionContext from within the process method,

private ExecutionContext executionContext;

@BeforeStep
public void beforeStep(StepExecution stepExecution)
{
    this.executionContext = stepExecution.getExecutionContext();
}

...and then in the process() method when I find one of the rows I want to log, I can do this,

this.executionContext.putInt( "i_ThoseRows", this.executionContext.getInt( "i_ThoseRows", 0 ) + 1 );

Finally I add another method to the ItemProcessor to print the result at the end of the step,

@AfterStep
public void afterStep(StepExecution stepExecution)
{
    System.out.println( "Number of 'Those rows': " + this.executionContext.getInt( "i_ThoseRows", 0 ) );
}

Hope it helps someone

like image 35
dogfight Avatar answered Sep 27 '22 20:09

dogfight