0

In the Custom Mapper, everywhere I checked, the mapping is done on basis of column index. Is there a way we can get the data on basis of column names?

So suppose I need to read a .csv file with 10 columns and I want only below five columns.

<bean id="ReportReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="linesToSkip" value="1" />
    <property name="resource" value="classpath:rawdata/file.csv" />
    <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="strict" value="False" />
                    <property name="names">
                        <array>
                            <value>columnName1</value>
                            <value>columnName2</value>
                            <value>columnName3</value>
                            <value>columnName4</value>
                            <value>columnName5</value>
                        </array>
                    </property>
                </bean>
            </property>
            <property name="fieldSetMapper">
                <bean
                    class="org.springframework.batch.item.file.mapping.PropertiesFieldSetMapper">
                </bean>
            </property>
        </bean>
    </property>
</bean>

Currently I have created a generic PropertiesFieldSetMapper class which I use for other jobs too.

public class PropertiesFieldSetMapper implements FieldSetMapper<Properties> {

@Override
public Properties mapFieldSet(FieldSet fieldSet) throws BindException {

    Properties properties = fieldSet.getProperties();

    return properties;
}

}

Now above set of code works fine if there are only 5 columns and in same order. When the column increases the code fails. For that we can implement Custom Mapper.

public class PropertiesFieldSetMapper implements FieldSetMapper<Properties> {

@Override
public Properties mapFieldSet(FieldSet fieldSet) throws BindException {

    //Properties properties = fieldSet.getProperties();

    Properties properties = new Properties();
    properties.setProperty("columnName1", fieldSet.readString(0));
    properties.setProperty("columnName2", fieldSet.readString(1));
    properties.setProperty("columnName3", fieldSet.readString(2));
    properties.setProperty("columnName4", fieldSet.readString(3));
    properties.setProperty("columnName5", fieldSet.readString(4));

    return properties;
}

}

In above code I have done the mapping on basis of column index. But this too fails if the order of the columns changes. Thus to make it robust, I want to map it via names and not column index.

Is there a way to achieve this?? Thanks in advance.

Pallav
  • 9
  • 1
  • Does this answer your question? [How to read only a subset columns in a CSV file using Spring batch FlatFileItemReader?](https://stackoverflow.com/questions/52869410/how-to-read-only-a-subset-columns-in-a-csv-file-using-spring-batch-flatfileitemr) – Mahmoud Ben Hassine Feb 24 '20 at 13:04
  • Thanks @MahmoudBenHassine but even I want the mapping on the basis of columns rather than indexes. Also when I just give the names(I am interested) in my batch-job xml file without the includedField tag, the fieldSet which I get in custom Mapper class is not consistent that is name and values do not match. – Pallav Feb 24 '20 at 15:21
  • And when I dont pass any names in the xml file, fieldSet just gives the tokenized values without name. Thus I cant do any operation as it says metadata not available. Again what I can do is get the values according to the indexes which I dont want. – Pallav Feb 24 '20 at 15:24
  • In that case, you need a custom mapper. – Mahmoud Ben Hassine Feb 25 '20 at 10:35

0 Answers0