当前位置: 首页 > 知识库问答 >
问题:

Spring批:org。springframework。一批项目ReaderNotOpenException:必须先打开读卡器才能读取

苏凯
2023-03-14

我读了很多相关的问题,但解决方案对我来说并不适用。

我得到了org.springframework.batch.item.ReaderNotOpenExctive:Reader必须打开才能读取异常。

以下是我的配置

@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("\t\t\t\t\t"+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方法中设置。看来杜彭没被叫来。问题是为什么?

共有3个答案

堵睿范
2023-03-14

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

嵇丰
2023-03-14

由于将读取器放入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批处理示例也返回ItemReader,所以我猜其他人也会遇到同样的问题。

谯和煦
2023-03-14

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

 类似资料:
  • 我正在使用JpaPagingItemReaderBuilder查询一个DB,结果被插入到另一个DB中。 查询返回的结果没有任何问题,但我得到了一个错误与读取器的返回,在处理器中,您可以检查我的编码和错误下面。 有谁能给我一点启示吗?为什么我不能处理结果?

  • 每次作业运行时,都在从不断增长的现有表中读取数据。我正在寻找Spring batch中的选项,以便在每次运行调度作业时只查询新记录。 如果我读了50000条记录,下一个时间表应该从50001开始。 我的想法是将ItemReader读取的最后一条记录的id(整个读卡器输出的最后一条,而不是每个块的最后一条)保存在DB中,并在后续的作业计划中使用。我将从主表返回按id排序的数据。 我怎么知道作者最后的

  • 我是Spring批次的新手。我需要在spring批处理中实现的任务如下: 需要从数据库读取一些元数据。 基于此元数据,我需要读取一些文件。 经过一些处理后,需要将这些值从文件写入数据库。 我的查询如下: c.另外,基于某些条件,我可能需要调用第三组阅读器。如何在步骤中有条件地调用读取器? 谢谢你看了我的帖子。我知道它很长。非常感谢任何帮助。另外,我想一个示例代码片段会帮助我更好地理解这一点。:)

  • CompositeItemWriter:当我需要将项目平均地分给Writer时,似乎会将所有读取的项目传递给所有的Writer。 BacktoBackPatternClassifier:我并不真正需要分类器,因为我是均匀地拆分项目。 有没有另一种方式,让一个读者和多个作者? 或者我可以在Writer中手动创建线程?

  • 我有一个要求,我需要从xls(其中存在一个名为netCreditAmount的列)中读取值并将值保存在数据库中。要求是从所有行中添加netCreditAmount的值,然后在数据库中仅为xls中的第一行设置此总和,其余行插入相应的netCreditAmounts。我应该如何在Spring Batch中进行实施。普通的阅读器、处理器和写入器工作正常,但我应该在哪里插入这个实现?谢谢!

  • 试图实现Spring批处理,但面临一个奇怪的问题,我们的类只执行了一次。 以下是细节。 如果我们在DB中有1000行。 我们的项目阅读器从DB中获取1000行,并将列表传递给 成功删除所有项目。 现在ItemReader再次尝试从数据库中获取数据,但没有找到,因此返回NULL,因此执行停止。 但是我们已经将批处理配置为使用调度器执行,这是每分钟执行一次。 现在,如果我们通过转储导入在DB中插入让我