要使用默认的BatchConfigurer,上下文必须包含不超过一个DataSource,找到2

时间:2017-05-29 06:43:03

标签: mysql spring-boot db2 spring-batch

我正在使用弹簧靴和弹簧批。对于元表我想使用mysql,并且我希望将db2用作数据库。当我实现获取错误时。

application.properties

spring.datasource.url = jdbc:mysql://localhost:3306/local
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

spring.seconddatasource.url=jdbc:db2://***************
spring.seconddatasource.username=******
spring.seconddatasource.password=****
spring.seconddatasource.driverClassName=com.ibm.db2.jcc.DB2Driver

BatchCongig.java

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    public DataSource dataSourceSecond;

    @Bean
    @ConfigurationProperties(prefix="spring.seconddatasource")
    public javax.sql.DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public javax.sql.DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public JdbcCursorItemReader<User> reader()
    {
        JdbcCursorItemReader<User> reader=new JdbcCursorItemReader<>();
        reader.setDataSource(dataSourceSecond);
        reader.setSql("Select ACCT_ID from ACCT_table FETCH FIRST 100 ROWS ONLY");
        reader.setRowMapper(new UserRowerMapper());
        return reader;
    }

    @Bean
    public UserItemProcessor processor()
    {
        return new UserItemProcessor();
    }

    @Bean
    public Step step1()
    {
        return stepBuilderFactory.get("step1").<User,User>chunk(10)
                .reader(reader())
                .processor(processor())
                .build();
    }

    @Bean
    public Job job1()
    {
        return jobBuilderFactory.get("jobakjkkj")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();

    }

}

错误堆栈

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at com.schwab.cat.SpringBatchDbReadApplication.main(SpringBatchDbReadApplication.java:10) [classes/:na]
Caused by: java.lang.IllegalStateException: To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2
    at org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.getConfigurer(AbstractBatchConfiguration.java:108) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration.initialize(SimpleBatchConfiguration.java:114) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$ReferenceTargetSource.createObject(SimpleBatchConfiguration.java:142) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.aop.target.AbstractLazyCreationTargetSource.getTarget(AbstractLazyCreationTargetSource.java:86) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at com.sun.proxy.$Proxy46.getJobInstances(Unknown Source) ~[na:na]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.getNextJobParameters(JobLauncherCommandLineRunner.java:131) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:212) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:231) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:123) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:117) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
    ... 6 common frames omitted

我找到一个jira https://jira.spring.io/browse/BATCH-2537,说“@Primary数据源与@EnableBatchProcessing无法使用多个数据源”如果这是正确的请告诉我如何才能实现相同目的。 我也发现了这个How to use 2 or more databases with spring?,但对我的情况没有帮助。

1 个答案:

答案 0 :(得分:0)

正如M. Deinum建议的那样,我也会将数据源的配置放在一个单独的文件中。

除此之外,配置文件中还存在以下问题:

  1. SpringBatch查找名为&#34; dataSource&#34;的数据源。 (注意大写S)。如果找不到,则查找找到的任何数据源。但是,如果它找到多个,则抛出异常 - &gt;你观察到的那个。

  2. 在配置文件中,创建两个数据源并注入一个(@Autowired Datasource dataSourceSecond)。这将导致下一个问题,因为您没有具有此名称的数据源。 (您只定义了数据源&#34; secondaryDataSource&#34;和&#34; primaryDataSource&#34;)。这也会导致异常。

  3. 以下是我如何组织配置

    @Configuration
    public DatasourceConfiguration {
    
        @Bean
        @ConfigurationProperties(prefix="spring.seconddatasource")
        public javax.sql.DataSource secondaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        // note the new name: dataSource -> this is the name springBatch is looking for
        @Bean
        @ConfigurationProperties(prefix="spring.datasource")
        public javax.sql.DataSource dataSource() {
            return DataSourceBuilder.create().build();
        }
    }
    
    
    @Configuration
    @EnableBatchProcessing
    @Import(DatasourceConfiguration.class)
    public class BatchConfiguration {
    
        @Autowired
        public JobBuilderFactory jobBuilderFactory;
    
        @Autowired
        public StepBuilderFactory stepBuilderFactory;
    
        // note the name
        @Autowired
        public DataSource secondaryDataSource;
    
    
        @Bean
        public JdbcCursorItemReader<User> reader()
        {
            JdbcCursorItemReader<User> reader=new JdbcCursorItemReader<>();
    
            // note the name
            reader.setDataSource(secondaryDataSource);
            reader.setSql("Select ACCT_ID from ACCT_table FETCH FIRST 100 ROWS ONLY");
            reader.setRowMapper(new UserRowerMapper());
            return reader;
        }
    
       ...
    

    我也对类似的问题写了一个更彻底的答案: I would like to create a spring batch project where batch does not use my datasource