Spring Batch: org.springframework.batch.item.ReaderNotOpenEx



我读了这么多相关的问题,但解决方案不适合我。

我得到了org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read异常。

下面是我的配置:

@Bean
@StepScope
public ItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) {
                final String [] header = { .. this part omitted for brevity ... };
                FlatFileItemReader<Player> reader = new FlatFileItemReader<Player>();

                System.out.println("ttttt"+inputZipfile);
                reader.setResource(new ClassPathResource(inputZipfile));
                reader.setLineMapper(new DefaultLineMapper<Player>() {{
                    setLineTokenizer(new DelimitedLineTokenizer() {{
                        setNames( header );
                    }});
                    setFieldSetMapper(new BeanWrapperFieldSetMapper<Player>() {{
                        setTargetType(Player.class);
                    }});
                }});
                reader.setComments( header );
                return reader;
}
@Bean
@StepScope
public ItemProcessor<Player, PlayersStats> processor(@Value("#{jobParameters[statType]}") String statType,
                                                                 @Value("#{jobParameters[season]}") String season){
                PlayersStatsProcessor psp = new PlayersStatsProcessor();
                psp.setStatisticType( StatisticType.valueOf(statType) );
                psp.setSeason( season );
                return psp;
}

@Bean
@StepScope
public ItemWriter<PlayersStats> writer(){
            return new CustomWriter();
}

@Bean
public Job generateStatisticsJob() {
        return this.jobs.get("generateStatisticsJob")
                .incrementer(new RunIdIncrementer())
                .start(processPlayerStats())
                //.end()
                .build();
}
@Bean
public Step processPlayerStats() {
           return this.steps.get("processPlayerStats")        
                        .<Player, PlayersStats> chunk(10)
                        .reader(reader(null))
                        .processor(processor(null,null))
                        .writer(writer())
                        .build();
}

inputZipFile变量设置正确,并且该文件存在于驱动器上。我检查了FlatFileItemReader代码,当reader类的reader成员未设置时,会发生ReaderNotOpenException。在doOpen方法中设置阅读器成员。看起来doOpen没有被调用。问题是为什么?

当我将阅读器bean的返回类型从Item更改为FlatFileItemReader时,问题消失了。我仍然不清楚为什么这是一个问题,因为chunk().reader()接受ItemReader作为输入。我假设在底层有一些AOP魔法,它执行FlatFileReader初始化并根据返回类型进行匹配。

由于您将阅读器放在StepScope中,bean返回类型应该是实现类型FlatFileItemReader:

@Bean
@StepScope
public FlatFileItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) {
            ...
            return reader;
}

如果指定了接口,则Spring代理只能访问接口ItemReader上指定的方法和注释,并且缺少重要的注释。在日志中也有一个警告(带有拼写错误):

2015-05-07 10:40:22,733 WARN  [main] org.springframework.batch.item.ItemReader is an interface.  The implementing class will not be queried for annotation based listener configurations.  If using @StepScope on a @Bean method, be sure to return the implementing class so listner annotations can be used.
2015-05-07 10:40:22,748 WARN  [main] org.springframework.batch.item.ItemReader is an interface.  The implementing class will not be queried for annotation based listener configurations.  If using @StepScope on a @Bean method, be sure to return the implementing class so listner annotations can be used. 

当前Spring Boot Batch示例也返回ItemReader,所以我猜其他人也会遇到同样的问题。

这是因为ItemReader没有open方法,使用StepScope将根据返回类型创建一个代理类。也可以返回ItemStreamReader

我已经修复了它:

reader.open(new ExecutionContext());

我认为你应该增加你的块大小在processPlayerStats()步骤bean类,即从块(10)块(100/更多可能是)。

我定义的方法如下:

    @Bean
    @StepScope
    public ItemReader<BP> BPReader(){
       
        JdbcCursorItemReader<BP> itemReader = new JdbcCursorItemReader<BP>();
        ...
        return itemReader;
    }

我在方法中定义的类型是ItemReader,它是一个接口,返回类型是JdbcCursorItemReader,它是它的子类。通过将返回类型定义更改为JdbcCursorItemReader解决了我的问题

不返回ItemReader,而是返回ItemStreamReader,因为它是ItemReaderItemStream接口的组合,因此它识别出需要调用open方法。

同样的问题。将阅读器的返回类型更改为实际实现,并添加阅读器

implements ItemStream

最新更新