Skip to content

Add compile-time safety to FlatFileItemReaderBuilder DSL #4929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

snowykte0426
Copy link

@snowykte0426 snowykte0426 commented Jul 23, 2025

Summary

This PR enhances the FlatFileItemReaderBuilder to prevent mutual
exclusivity violations between targetType() and fieldSetMapper()
methods at compile time rather than runtime, resolving issue #4888.

Changes

  • Enhanced DSL with Stage Pattern: Introduced
    FieldSetMapperStage<T> and TargetTypeStage<T> interfaces
  • Compile-time Safety: Prevents incompatible method combinations
    through type system

Implementation Details

Before (Runtime Error)

// This would compile but fail at runtime
new FlatFileItemReaderBuilder<Foo>()
    .name("fooReader")
    .resource(resource)
    .lineTokenizer(tokenizer)
    .targetType(Foo.class)
    .fieldSetMapper(mapper)  // IllegalStateException at runtime
    .build();

After (Compile-time Safety)

  // This won't compile - IDE shows error immediately
  new FlatFileItemReaderBuilder<Foo>()
      .name("fooReader")
      .resource(resource)
      .lineTokenizer(tokenizer)
      .targetType(Foo.class)
      .fieldSetMapper(mapper)  // Compile error: method not available
      .build();

Usage Patterns

  // Pattern 1: Using targetType() - returns TargetTypeStage<T>
  new FlatFileItemReaderBuilder<Foo>()
      .name("fooReader")
      .resource(resource)
      .delimited()
      .names("field1", "field2")
      .targetType(Foo.class)
      .beanMapperStrict(true)  // targetType-specific methods available
      .build();

  // Pattern 2: Using fieldSetMapper() - returns FieldSetMapperStage<T>
  new FlatFileItemReaderBuilder<Foo>()
      .name("fooReader")
      .resource(resource)
      .lineTokenizer(tokenizer)
      .fieldSetMapper(fieldSet -> new Foo())
      .saveState(false)  // common methods available
      .build();

Fixes
Issue #4888

Enhance FlatFileItemReaderBuilder to prevent mutual exclusivity violations
between targetType() and fieldSetMapper() methods at compile time rather
than runtime.

The implementation uses a stage-based DSL pattern where:
- fieldSetMapper() returns FieldSetMapperStage<T> interface
- targetType() returns TargetTypeStage<T> interface
- Each stage only exposes methods compatible with the chosen mapping strategy

This resolves GitHub issue spring-projects#4888 by providing immediate IDE feedback when
developers attempt to use incompatible method combinations, improving
developer experience and preventing runtime errors.

Signed-off-by: snowykte0426 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant