We help IT Professionals succeed at work.

Spring Batch: Include count of records in File Header.

Prashant Vasha
Prashant Vasha used Ask the Experts™
on
I am writing a standalone application using Spring Batch. The below is my batch job configuration:
<batch:job id="sampleBatchJob">
        <batch:step id="createFile">
            <tasklet>
                <batch:chunk reader="sampleReader" writer="sampleFileWriter" processor="sampleRecordProcessor" commit-interval="500"/>
            </tasklet>
        </batch:step>
        <batch:listeners>
            <batch:listener ref="sampleStepExecutionListener" />
            <batch:listener ref="executionContextPromotionListener" />
        </batch:listeners>
    </batch:job>
    <bean id="executionContextPromotionListener"
          class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
        <property name="keys" value="recordCount" />
    </bean>
    <bean id="outputResource" class="org.springframework.core.io.ClassPathResource">
        <constructor-arg type="java.lang.String" value="sample.csv" />
    </bean>

    <bean id="sampleReader" class="test.SampleDataItemReader" scope="step"/>

    <bean id="sampleFileWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
        <property name="resource" ref="outputResource"/>
        <property name="shouldDeleteIfExists" value="true" />
        <property name="headerCallback" ref="sampleFileWriterCallback" />
        <property name="lineAggregator">
            <bean class="test.SampleCustomLineAggregator" >
                <property name="delimiter" value="," />
            </bean>
        </property>
    </bean>

    <bean id="sampleFileWriterCallback" class="test.SampleFileHeaderWriterCallback"/>

    <bean id="sampleRecordProcessor" class="test.SampleRecordProcessor"/>

    <bean id="sampleStepExecutionListener" class="test.SampleStepExecutionListener"/>

Open in new window


I have to include the count of records in the File Header and for the same I have declared a property "recordCount" in executionContextPromotionListener. I am setting the value for the property in the ItemReader implementation using the ExecutionContext.

But before the ItemReader is invoked, the Header Callback for the ItemWriter is invoked and the writeHeader(Writer) is executed. Also, I do not have access to the ExecutionContext object when the writeHeader(Writer) is executed.

Any suggestions, how I can pass the value from the reader to the FileHeaderWriterCallBack implementation?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
On further investigations, I found that the HeaderCallback is triggered before the Reader. One way to do is write a tasklet to return the count of records and include it in the ExecutionContext. Access the ExecutionContext in the HeaderCallback and retrieve the count and update it. I find this to be an overhead and have therefore decided to create my own Custom FlatFileItemWriter implementation where the header will be written before the writer starts writing the records to the file. Work is in progress and will share once I have completed the implementation and the desired results are achieved.