2

Skip exception class functionality is not working properly when MongoItemreader is being used.

Issues: 1. Spring batch is stuck at a particular data row (in my case 15). It calls MessageContextReadConverter and onReadError for same row number 15 -- 3 times. 2. skiplistener is never invoked.

Scenario: Suppose 20 rows are fetched from MongoDB and at row number 15 configurable exception ".ConversionFailedException" is thrown from a custom class derived from Converter, (MessageContextReadConverter implements Converter) . MessageContextReadConverter is set during mongoTemplate creation,. Now, exception thrown at row number 15 is received in custom readlistener (public void onReadError(Exception ex)).

Configuration XML:

<context:property-placeholder location="classpath:application.properties" />

<context:component-scan base-package="com.XXX.YYY.batch.kernel" />
<context:component-scan base-package="com.XXX.YYY.batch.dao" />

<context:annotation-config />

<!-- Enable Annotation based Declarative Transaction Management -->
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />

<!-- Creating TransactionManager Bean, since JDBC we are creating of type DataSourceTransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<batch:job id="txnLogJob" restartable="false">
    <batch:step id="txnload">
        <tasklet allow-start-if-complete="true" transaction-manager="transactionManager">
            <chunk reader="txnLogReader" processor="txnLogProcessor"
                writer="txnLogItemWriter" commit-interval="10" skip-limit="3">
                <skippable-exception-classes>
                    <include class="org.springframework.core.convert.ConversionFailedException" />
                </skippable-exception-classes>                  
            </chunk>
            <listeners>
                <listener ref="stepListener" />
                <listener ref="chunklistener" />
                <listener ref="readlistener" />
                <listener ref="skiplistener" />
            </listeners>
        </tasklet>
    </batch:step>

    <batch:listeners>
        <batch:listener ref="completionListener" />
    </batch:listeners>
</batch:job>

<bean id="txnLogReader" class="org.springframework.batch.item.data.MongoItemReader"
    scope="step">
    <property name="template" ref="mongoTemplate" />
    <property name="query" value=" { }" />
    <property name="pageSize" value="50" />
    <property name="sort">
        <map>
            <entry key="audit_info.created_on"
                value="#{T(org.springframework.data.domain.Sort.Direction).ASC}" />
        </map>
    </property>
    <property name="collection" value="txnlog" />
    <property name="targetType" value="com.XXX.YYY.kernel.msg.MessageContext" />
</bean>

<bean id="completionListener"
    class="com.XXX.YYY.batch.listeners.JobCompletionNotificationListener" />

<bean id="stepListener"
    class="com.XXX.YYY.batch.listeners.StepExecutionListener" />

<bean id="chunklistener"
    class="com.XXX.YYY.batch.listeners.ChunkExecutionListener" />

<bean id="readlistener"
    class="com.XXX.YYY.batch.listeners.ReadExecutionListener" />

<bean id="skiplistener"
    class="com.XXX.YYY.batch.listeners.SkipExecutionListener" />


<bean id="jobParametersDAOImpl" class="com.XXX.YYY.batch.dao.JobParametersDAOImpl" />

<bean id="batchLoader" class="com.XXX.YYY.batch.kernel.BatchLoader" />

<bean id="batchjobParameter" class="com.XXX.YYY.batch.dao.Batch_Job_Parameters" />


<!-- <bean id="reportWriter" class="org.springframework.batch.item.data.MongoItemWriter"> 
    <property name="template" ref="mongoTemplate" /> <property name="collection" 
    value="txnlog" /> name of the collection to write </bean> -->

<bean id="txnLogItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"
    scope="step">
    <property name="shouldDeleteIfExists" value="true" />
    <property name="resource" value="file:target/test-outputs/output.txt" />
    <property name="lineAggregator">
        <bean
            class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
    </property>
</bean>

<bean id="txnLogProcessor"
    class="com.XXX.YYY.batch.processor.MessageContextItemProcessor" />

<bean id="jobLauncher"
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
</bean>

<bean id="jobRepository"
    class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="databaseType" value="MYSQL" />
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
</bean>

<bean id="dataSource" class="com.XXX.YYY.common.DataSource"
    destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="connectionProperties" value="${jdbc.connectionProperties}" />
    <property name="initialSize" value="${jdbc.initialSize}" />
    <property name="maxTotal" value="${jdbc.maxTotal}" />
    <property name="maxIdle" value="${jdbc.maxIdle}" />
    <property name="minIdle" value="${jdbc.minIdle}" />
    <property name="maxWaitMillis" value="${jdbc.maxWaitMillis}" />
    <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
    <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
    <property name="testOnReturn" value="${jdbc.testOnReturn}" />
    <property name="validationQuery" value="${jdbc.validationQuery}" />
</bean>

anish Sh
  • 21
  • 2

0 Answers0