Implementing Custom Skip Policy

In my previous posts under Spring Batch, I explained with example how to use built in out of the box skip policies.

In this post I will explain how to create our own custom skip policy and use it.

To create our own custom skip policy we need to implement the interface org.springframework.batch.core.step.skip.SkipPolicy as shown below

MySkipPolicy


1  package package27;
2  
3  import org.springframework.batch.core.step.skip.SkipLimitExceededException;
4  import org.springframework.batch.core.step.skip.SkipPolicy;
5  
6  public class MySkipPolicy implements SkipPolicy {
7   @Override
8   public boolean shouldSkip(Throwable throwable, int skipCount) throws SkipLimitExceededException {
9       System.out.println("SkipCount: " + skipCount);
10      if(skipCount == 5) {
11          return false;
12      }
13      return true;
14  }
15 }

In the above code, we implement SkipPolicy interface and provide implementation for shouldSkip method.

The shouldSkip method takes two arguments
1) Throwable –> the exception thrown when processing a record
2) skipCount –> a number representing the number of exception (i.e., argument 1) thrown

The method returns a boolean, if true is returned, the processing continues otherwise the processing stops.

In our code, if the skipCount reaches 5 we are returning false and stopping the processing midway.

Next i will show you how to integrate this skip policy with the batch job.

Below is the xml configuration


1   <bean id="mySkipPolicy" class="package27.MySkipPolicy"/>
2   
3   <batch:job id="importEmployees">
4       <batch:step id="readWriteEmployees">
5           <batch:tasklet>
6               <batch:chunk reader="reader" writer="writer" commit-interval="50" skip-policy="mySkipPolicy"/>
7           </batch:tasklet>
8       </batch:step>
9   </batch:job>

In the above xml code, at line 1, I create a bean definition for MySkipPolicy class with id “mySkipPolicy”.

Next I refer this bean at line 6 and set it to attribute “skip-policy”.

In this way we can integrate the custom skip policy with the batch job.

Below is the complete xml configuration for your reference


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
    
    <bean id="employee" class="package27.Employee" scope="prototype"/>
    
    <bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
        <property name="resource" value="file:FileInput8.txt"/>
        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <property name="lineTokenizer">
                    <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                        <property name="names" value="id,name,status,salary"/>
                    </bean>
                </property>
                <property name="fieldSetMapper">
                    <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                        <property name="prototypeBeanName" value="employee"/>
                    </bean>
                </property>
            </bean>
        </property> 
    </bean>
    
    <bean id="writer" class="org.springframework.batch.item.file.FlatFileItemWriter">
        <property name="resource" value="file:FileOutput.txt"/>
        <property name="lineAggregator">
            <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                <property name="fieldExtractor">
                    <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                        <property name="names" value="id,name,status,salary"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    
    <bean id="mySkipPolicy" class="package27.MySkipPolicy"/>
    
    <batch:job id="importEmployees">
        <batch:step id="readWriteEmployees">
            <batch:tasklet>
                <batch:chunk reader="reader" writer="writer" commit-interval="50" skip-policy="mySkipPolicy"/>
            </batch:tasklet>
        </batch:step>
    </batch:job>
    
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
    
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
    
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
</beans>

Leave a Reply