2015-10-14 63 views
2

我正在關注Spring doc for creating batch service。我調整了它to store the data in MongoDb。現在我想添加一個從MongoDb集合讀​​取的步驟,進程&寫入另一個集合。我發現了一些使用MongoDb的spring批處理教程,但他們使用XML文件來定義豆類&顯得過時了。如何使用Annotations將另一步添加到Spring批處理作業?

@Configuration 
@EnableBatchProcessing 
@Import(SpringMongoConfig.class) 
public class BatchConfiguration { 

    @Autowired 
    private SpringMongoConfig springMongoConfig; 

    private static final Logger log = LoggerFactory.getLogger(BatchConfiguration.class); 
    private static final String csvFileName = "sample-data.csv", 
     recordCollectionName = "records", 
     processedRecordCollectionName = "processedRecords"; 

    @Bean 
    public Job importUserJob(JobBuilderFactory jobs, Step s1, Step s2, JobExecutionListener listener) { 
    return jobs.get("importUserJob") 
     .incrementer(new RunIdIncrementer()) 
     .listener(listener) 
     .flow(s1) 
     .next(s2) 
     .end() 
     .build(); 
    } 

    @Bean 
    public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<Record> csvRecordReader, 
      ItemWriter<Record> mongoRecordWriter) { 
    return stepBuilderFactory.get("step1"). 
     <Record, Record> chunk(10). 
     reader(csvRecordReader()) 
     .writer(mongoRecordWriter()) 
     .build(); 
    } 

    @Bean 
    public Step step2(StepBuilderFactory stepBuilderFactory, ItemReader<Record> mongoRecordReader, 
      ItemWriter<processedRecord> mongoprocessedRecordWriter, ItemProcessor<Record, processedRecord> processor) { 
    return stepBuilderFactory.get("step2") 
     .<Record, processedRecord> chunk(10) 
     .reader(mongoRecordReader) 
     .processor(processor) 
     .writer(mongoprocessedRecordWriter) 
     .build(); 
    } 

    // tag::readerwriter[1] 
    @Bean 
    public ItemReader<Record> csvRecordReader() { 
    FlatFileItemReader<Record> reader = new FlatFileItemReader<Record>(); 
    reader.setResource(new ClassPathResource(csvFileName)); 
    reader.setLineMapper(new DefaultLineMapper<Record>() { 
     { 
     setLineTokenizer(new DelimitedLineTokenizer() { 
      { 
      setNames(new String[] { "id", "firstName", "lastName" }); 
      } 
     }); 
     setFieldSetMapper(new BeanWrapperFieldSetMapper<Record>() { 
      { 
      setTargetType(Record.class); 
      } 
     }); 
     } 
    }); 
    return reader; 
    } 

    @Bean 
    public ItemWriter<Record> mongoRecordWriter() { 
    MongoItemWriter<Record> writer = new MongoItemWriter<Record>(); 
    try { 
     writer.setTemplate(springMongoConfig.mongoTemplate()); 
    } catch (Exception e) { 
     log.error(e.toString()); 
    } 
    writer.setCollection(recordCollectionName); 
    return writer; 
    } 
    // end::readerwriter[1] 

    // tag::readerprocessorwriter[2] 
    @Bean 
    public ItemReader<Record> mongoRecordReader() { 
    MongoItemReader<Record> reader = new MongoItemReader<Record>(); 
    try { 
     reader.setTemplate(springMongoConfig.mongoTemplate()); 
    } catch (Exception e) { 
     log.error(e.toString()); 
    } 
    reader.setCollection(recordCollectionName); 
    return reader; 
    } 

    @Bean 
    public ItemProcessor<Record, processedRecord> processor() { 
    return new RecordItemProcessor(); 
    } 

    @Bean 
    public ItemWriter<processedRecord> mongoprocessedRecordWriter() { 
    MongoItemWriter<processedRecord> writer = new MongoItemWriter<processedRecord>(); 
    try { 
     writer.setTemplate(springMongoConfig.mongoTemplate()); 
    } catch (Exception e) { 
     log.error(e.toString()); 
    } 
    writer.setCollection(processedRecordCollectionName); 
    return writer; 
    } 
    // end::readerprocessorwriter[2] 
} 

我收到以下錯誤:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'importUserJob' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.core.Step]: : Error creating bean with name 'step1' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.item.ItemReader]: : Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'step1' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.item.ItemReader]: : Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:687) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:967) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:956) 
    at com.xyz.abc.batch.App.main(App.java:18) 
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'step1' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.item.ItemReader]: : Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) 
    ... 17 common frames omitted 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) 
    ... 31 common frames omitted 
Caused by: java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.util.Assert.state(Assert.java:385) 
    at org.springframework.batch.item.data.MongoItemReader.afterPropertiesSet(MongoItemReader.java:200) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) 
    ... 42 common frames omitted 

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'importUserJob' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.core.Step]: : Error creating bean with name 'step1' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.item.ItemReader]: : Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'step1' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.item.ItemReader]: : Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:687) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:967) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:956) 
    at com.xyz.abc.batch.App.main(App.java:18) 
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'step1' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.item.ItemReader]: : Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) 
    ... 17 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoRecordReader' defined in class path resource [com/xyz/abc/batch/BatchConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) 
    ... 31 more 
Caused by: java.lang.IllegalStateException: A type to convert the input into is required. 
    at org.springframework.util.Assert.state(Assert.java:385) 
    at org.springframework.batch.item.data.MongoItemReader.afterPropertiesSet(MongoItemReader.java:200) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) 
    ... 42 more 

回答

3

我認爲你只是缺少setTargetType來電您mongoRecordReader()。有關詳細信息,請參閱MongoItemReader的docs

此外,看一看的afterPropertiesSet方法:

@Override 
public void afterPropertiesSet() throws Exception { 
    Assert.state(template != null, "An implementation of MongoOperations is required."); 
    Assert.state(type != null, "A type to convert the input into is required."); 
    Assert.state(query != null, "A query is required."); 
    Assert.state(sort != null, "A sort is required."); 
} 

還有一些其他必填字段。

+0

非常感謝,它解決了我的另一個錯誤。但我仍然得到http://hastebin.com/zowugukoje.avrasm。我不知道'Job'bean是如何自動連接以接收兩個'Step'的,所以我只是將'Step s2'作爲另一個參數添加到'importUserJob'方法中。 – parth

+1

您需要將您的'Step'參數完全限定爲'importUserJob'方法。 '@Qualifier(「step1」)s1,@Qualifier(「step2」)s2' – leeor

+0

非常感謝@leeor :) – parth

相關問題