Vicky
Vicky

Reputation: 17425

Spring batch database to fixed format file program - issue with output into the file

I have a spring batch program where I am writing from database to a fixed format file.

My database table consist of 5 columns. All the columns contain description about some product. The column are of type varchar with each sized 200.

I am reading the descriptions from the columns in to my pojo as 5 String properties viz. desc1, desc2, desc3, desc4, desc5.

My item writer looks like below:

<beans:bean id="DbToFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
    <beans:property name="resource" value="file:c:\TestData\output.dat" /> 

    <beans:property name="lineAggregator">
        <beans:bean class="org.springframework.batch.item.file.transform.FormatterLineAggregator">
            <beans:property name="fieldExtractor">
                <beans:bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                 <beans:property name="names" value="desc1, desc2, desc3, desc4, desc5" /> 
                </beans:bean>
            </beans:property>

            <beans:property name="format" value="%-20s%-30s%-30s%-30s%-30s" /> 
        </beans:bean>
    </beans:property>
</beans:bean>

As shown I want desc1 to be in a fixed length field of 20 characters and desc2 through desc4 into fixed length field of 30 characters each into the file.

However, the issue is, I am getting the whole desc string irrespective of the size. That is, if desc1 is 40 characters from database, it is coming as 40 characters in the file as well.

I feel it should only take the first 20 characters and ignore the rest.

What is the issue? Is it a bug or am I doing something wrong ?

Thanks for reading!

Upvotes: 1

Views: 4600

Answers (2)

Michael Pralow
Michael Pralow

Reputation: 6630

the FormatterLineAggregator uses String.format() under the hood, so you could use the right Formatter syntax(*) to get what you want

two examples to show what you missed in your formatter syntax

wrong:

    // formatted to print out 5 characters minimum
    String wrong = String.format("%-5s", new Object[]{"1234567890"});
    System.out.println(wrong);
    // prints: 1234567890

correct:

    // formatted to print out 5 characters minimum AND 6 characters maximum
    String correct = String.format("%-5.6s", new Object[]{"1234567890"});
    System.out.println(correct);
    // prints: 123456

(*) this is mentioned in the javadoc of the FormatterLineAggregator too

Upvotes: 3

dma_k
dma_k

Reputation: 10649

The simplest solution will be to change your reader, e.g. your can create SQL view over your table or write a custom SQL query like:

select substr(desc1,1,20), substr(desc2,1,20), ... from my_table

Alternatively you can write your own implementation of FieldExtractor interface that should aggregate BeanWrapperFieldExtractor. After calling the BeanWrapperFieldExtractor#extract() it should crop all values by given maximum size.

Upvotes: 1

Related Questions