Spring Пакет: org.springframework.batch.item.ReaderNotOpenException: Reader должен быть открыт, прежде чем его можно будет прочитать
Я прочитал связанные вопросы, но решения для меня не работают.
Я получаю исключение 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("\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, и ReaderNotOpenException возникает, когда член читателя класса читателя не установлен. Элемент чтения установлен в doOpen.
Похоже, doOpen не вызван. Вопрос в том, почему?
Ответы
Ответ 1
Проблема исчезла, когда я изменил возвращаемый тип моего читателя bean с Item на FlatFileItemReader. Мне все еще не ясно, почему это проблема, поскольку chunk(). Reader() принимает ItemReader в качестве входа. Я предполагаю, что под капотом есть какая-то AOP-магия, которая делает FlatFileReader init и соответствует типу return.
Ответ 2
Поскольку вы помещаете читателя в 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 также возвращает ItemReader, поэтому я думаю, что другие люди будут бороться с теми же проблемами.
Ответ 3
Это потому, что ItemReader не имеет открытого метода, используя hte. StepScope создаст прокси-класс на основе типа возврата. Также нормально возвращать ItemStreamReader
Ответ 4
Я думаю, вы должны увеличить размер вашего куска в processPlayerStats() step bean class, т.е. из chunk (10) в chunk (может быть 100 и более).
Ответ 5
Такая же проблема.
Изменение возвращаемого типа моего читателя на реальную реализацию и добавление к читателю
implements ItemStream
Сделал трюк для меня
Ответ 6
Метод, который я определил, выглядит следующим образом:
@Bean
@StepScope
public ItemReader<BP> BPReader(){
JdbcCursorItemReader<BP> itemReader = new JdbcCursorItemReader<BP>();
...
return itemReader;
}
Ответ 7
Я исправил это:
reader.open(new ExecutionContext());