How to use BeanWrapperFieldSetMapper to map a subset of fields?
<p>I have a Spring batch application where <code>BeanWrapperFieldSetMapper</code> is used to map fields using a prototype object. However, the CSV file that is being read (via a <code>FlatFileItemReader</code>) contains one (indicator) field that determines the mapping of another field. If the indicator field has a value of Y, then the value of the another field should be mapped to property <code>foo</code> otherwise it should be mapped to property <code>bar</code>.</p>

<p>I know that I can use a custom <code>FieldSetMapper</code> to do this, but then I have to code the mapping all of the other fields (of which there are a quite a few). Alternatively, I could do this post reading via an <code>ItemProcessor</code> but then my domain (prototype) object must have a property representing the indicator field (which I prefer not to do since it is not really part of the business domain).</p>

<p>Is it possible to perhaps use a custom <code>FieldSetMapper</code> to only map these custom fields and delegate the other mappings to <code>BeanWrapperFieldSetMapper</code>? Or is there some other better way to solve for this?</p>

<p>Here is my current attempt to use a custom <code>FieldSetMapper</code> and delegate to <code>BeanWrapperFieldSetMapper</code>:</p>

<pre><code>public class DelegatedFieldSetMapper extends BeanWrapperFieldSetMapper&lt;MyProtoClass&gt; {

    @Override
    public MyProtoClass mapFieldSet(FieldSet fieldSet) throws BindException {       
        String indicator = fieldSet.readString("indicator");
        Properties fieldProperties = fieldSet.getProperties();

        if (indicator.equalsIgnoreCase("y")) {
            fieldProperties.put("test.foo", fieldSet.readString("value");
        } else {
            fieldProperties.put("test.bar", fieldSet.readString("value");
        }

        fieldProperties.remove("indicator");
        Set&lt;Object&gt; keys = fieldProperties.keySet();
        List&lt;String&gt; names = new ArrayList&lt;String&gt;();
        List&lt;String&gt; values = new ArrayList&lt;String&gt;();      
        for (Object key : keys) {
            names.add((String) key);
            values.add((String) fieldProperties.getProperty((String) key));
        }
        DefaultFieldSet domainObjectFieldSet = new DefaultFieldSet(names.toArray(new String[names.size()]), values.toArray(new String[values.size()]));     
        return super.mapFieldSet(domainObjectFieldSet);
    }

}
</code></pre>

<p>However, a FlatFileParseException is thrown. The relevant parts of the batch config class are as follows:</p>

<pre><code>@Configuration
@EnableBatchProcessing
public class BatchConfiguration { 

    @Value("${file}")
    private File file;

    @Bean
    @Scope("prototype")
    public MyProtoClass () {
        return new MyProtoClass();
    }

    @Bean
    public ItemReader&lt;MyProtoClass&gt; reader(LineMapper&lt;MyProtoClass&gt; lineMapper) {
        FlatFileItemReader&lt;MyProtoClass&gt; flatFileItemReader = new FlatFileItemReader&lt;MyProtoClass&gt;();
        flatFileItemReader.setResource(new FileSystemResource(file));
        final int NUMBER_OF_HEADER_LINES = 1;
        flatFileItemReader.setLinesToSkip(NUMBER_OF_HEADER_LINES);
        flatFileItemReader.setLineMapper(lineMapper);
        return flatFileItemReader;
    }

    @Bean 
    public LineMapper&lt;MyProtoClass&gt; lineMapper(LineTokenizer lineTokenizer, FieldSetMapper&lt;MyProtoClass&gt; fieldSetMapper) {
        DefaultLineMapper&lt;MyProtoClass&gt; lineMapper = new DefaultLineMapper&lt;MyProtoClass&gt;();
        lineMapper.setLineTokenizer(lineTokenizer);
        lineMapper.setFieldSetMapper(fieldSetMapper);
        return lineMapper;
    }

    @Bean
    public LineTokenizer lineTokenizer() {
        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();        
        lineTokenizer.setNames(new String[] {"value", "test.bar", "test.foo", "indicator"});
        return lineTokenizer;
    }

    @Bean
    public FieldSetMapper&lt;MyProtoClass&gt; fieldSetMapper(PropertyEditor emptyStringToNullPropertyEditor) {
        BeanWrapperFieldSetMapper&lt;MyProtoClass&gt; fieldSetMapper = new DelegatedFieldSetMapper();
        fieldSetMapper.setPrototypeBeanName("myProtoClass");
        Map&lt;Class&lt;String&gt;, PropertyEditor&gt; customEditors = new HashMap&lt;Class&lt;String&gt;, PropertyEditor&gt;();
        customEditors.put(String.class, emptyStringToNullPropertyEditor);
        fieldSetMapper.setCustomEditors(customEditors);
        return fieldSetMapper;

    }
</code></pre>

<p>Finally, the CSV flat file look like this:</p>

<pre><code>value,bar,foo,indicator
abc,,,y
xyz,,,n
</code></pre>