0

I tried implementing Spring batch. Here I'm trying to save data from text file to save in database. I'm getting NPE while processing.

@Configuration
public class JobConfig {

@Value("${inputFile}") 
private Resource resource;

@Autowired
private ResourceLoader resourceLoader;

private JobBuilderFactory jobBuilderFactory;
private StepBuilderFactory stepBuilderFactory;

@Autowired
public JobConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
    this.jobBuilderFactory = jobBuilderFactory;
    this.stepBuilderFactory = stepBuilderFactory;
}

@Bean
public Job job() {
    return this.jobBuilderFactory.get("JOB-Load")
            .start(fileReadingStep())
            .build();
}

@Bean
public Step fileReadingStep() {
    return stepBuilderFactory.get("File-Read-Step1")
            .<Student,Student>chunk(5)
            .reader(itemReader())
            .processor(new Processer())
            .writer(new Writer())
            .build();
}

@Bean
public FlatFileItemReader<Student> itemReader() {
    FlatFileItemReader<Student> flatFileItemReader = new FlatFileItemReader<>();
    flatFileItemReader.setResource(resource);
    flatFileItemReader.setName("File-Reader");
    flatFileItemReader.setStrict(false);
    flatFileItemReader.setLineMapper(LineMapper());
    return flatFileItemReader;
}

@Bean
public LineMapper<Student> LineMapper() {
    DefaultLineMapper<Student> defaultLineMapper = new DefaultLineMapper<Student>();
    FixedLengthTokenizer fixedLengthTokenizer = new FixedLengthTokenizer();
    fixedLengthTokenizer.setNames(new String[] { "name"});
    fixedLengthTokenizer.setColumns(new Range[] { new Range(1, 5)});
    fixedLengthTokenizer.setStrict(false);

    defaultLineMapper.setLineTokenizer(fixedLengthTokenizer);
    defaultLineMapper.setFieldSetMapper(new DefaultFieldSetMapper());

    return defaultLineMapper;
}

}

Writer Class

@Component
public class Writer implements ItemWriter<Student> {

@Autowired
private StudentRepo repo;

@Override
public void write(List<? extends Student> items) throws Exception {
    for(Student s:items) {
        System.out.println(s.getName());
    }
    try {
    repo.saveAll(items);
    }catch (Exception e) {
        e.printStackTrace();
    }
}
}

here I'm used JPARepository to save my text file data into database in my custom writer class. Here StudentRepo is null.

Why it's null ? I tried another method method used same StudentRepo to store in db manually there is no issue. Only in writer class it's null.

  • There seems to be a problem with your spring configuration. More details needed. – Henry Nov 13 '21 at 07:00
  • I created one controller and saved the data by using same repository , Not getting any error. Only inside ItemWriter getting NPE. I debugged I got null in repo. – Codinghubby Nov 13 '21 at 07:07
  • How are you getting the instance of `Writer` where `Writer.writer()` is being called? – Sree Kumar Nov 13 '21 at 07:59

1 Answers1

1

In fileReadingStep, you do not use the Writer bean that gets created through the @Component annotation. You create a new Writer instance which the Spring context is unaware of wherefore the repo field is not set and remains null.

You need to inject the Writer bean like you inject the ResourceLoader or the JobBuilderFactory and then use the bean in fileReadingStep.

Henning
  • 3,055
  • 6
  • 30