Skip to content

RecordFieldExtractor in FlatFileItemWriterBuilder doesn't reflect names() setting #4916

@kyb4312

Description

@kyb4312

This is related to spring-projects/spring-batch#4908, which points out that using names() with a record type and sourceType() might seem redundant. While that discussion raises a valid concern, this issue is coming from a slightly different angle: it would be helpful if the names() setting actually worked when a record is used with sourceType(). That way, developers wouldn't be surprised when their field selections are silently ignored.


Bug description

When using FlatFileItemWriterBuilder’s build() method with sourceType() set to a record class and specifying field names via names(), the RecordFieldExtractor used internally ignores the names() configuration.
In contrast, when sourceType() is not specified, the BeanWrapperFieldExtractor honors the names() configuration as expected.

This inconsistency can cause confusion, as the same record type behaves differently depending on whether sourceType() is provided.


Steps to reproduce

public record MyRecord(String name, int age, String address) {}

FlatFileItemWriter<MyRecord> writer = new FlatFileItemWriterBuilder<MyRecord>()
    .name("myRecordWriter")
    .resource(new FileSystemResource("output.csv"))
    .sourceType(MyRecord.class)  // triggers RecordFieldExtractor
    .names("name", "age")        // currently ignored
    .delimited()
    .build();

Expected output: name, age
Actual output: name, age, address


Suggested Fix

Update the builder to pass names into RecordFieldExtractor:

FlatFileItemWriterBuilder.build()

Before:

if (this.sourceType != null && this.sourceType.isRecord()) {
    this.fieldExtractor = new RecordFieldExtractor<>(this.sourceType);
}

After:

if (this.sourceType != null && this.sourceType.isRecord()) {
    RecordFieldExtractor<T> extractor = new RecordFieldExtractor<>(this.sourceType);
    extractor.setNames(this.names.toArray(new String[this.names.size()]));
    this.fieldExtractor = extractor;
}

This would make the behavior consistent and avoid surprises.


Let me know if you'd like a pull request with this change - I'd be happy to help!

powerd by KILL-9 💀

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions