【问题标题】:Spring Boot Start Application Error when trying to configure seperate datasource for spring batch schema and application尝试为 Spring Batch 模式和应用程序配置单独的数据源时 Spring Boot 启动应用程序错误
【发布时间】:2019-04-02 19:18:58
【问题描述】:

我们的应用程序使用 Oracle 11.2 作为数据库。因为不想将“春季批处理元数据”表与常规应用程序表混合,所以创建了一个新模式。但是,当尝试配置两个单独的数据源时,不断出现以下错误:

       //configuration first datasource

        @Configuration
        @EnableBatchProcessing
        public class BatchConfig{
            private static final Logger logger = LoggerFactory.getLogger(ReutersMarketDataReadConfig.class);

            ..

            @Bean
            @ConfigurationProperties(prefix = "spring.batch.datasource")
            public DataSource getBatchDataSource() {
            return DataSourceBuilder.create().build();
            }
        ....
        }


        //second data source
        @Configuration
        @EnableTransactionManagement
        @EnableJpaRepositories(
            entityManagerFactoryRef = "appEntityManagerFactory",
            transactionManagerRef = "appTransactionManager",
            basePackages = {"com.xyz.abc.repository" }
        )
        public class ApplicationDBConfig {

            @Primary
            @Bean(name = "appDataSource")
            @ConfigurationProperties(prefix = "spring.datasource")
            public DataSource dataSource() {
            return DataSourceBuilder.create().build();
            }

            @Primary
            @Bean(name = "appEntityManagerFactory")
            public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                @Qualifier("appDataSource") DataSource dataSource) {
            return builder.dataSource(dataSource).packages("com.xyz.abc.model").persistenceUnit("app").build();
            }

            @Primary
            @Bean(name = "appTransactionManager")
            public PlatformTransactionManager transactionManager(
                @Qualifier("appEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
            return new JpaTransactionManager(entityManagerFactory);
            }
        }

错误:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[30m2019-04-02 14:56:16,706[0;39m [1;31mERROR[0;39m [[34mrestartedMain[0;39m] [33morg.springframework.boot.SpringApplication[0;39m: Application run failed
            org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobInvokerController': Unsatisfied dependency expressed through field 'processLiborFeedJob'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'processLiborFeedJob' defined in class path resource [com/db/sts/marketdata/batch/config/ReutersMarketDataReadConfig.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'taskBatchExecutionListener' defined in class path resource [org/springframework/cloud/task/batch/configuration/TaskBatchAutoConfiguration$TaskBatchExecutionListenerAutoconfiguration.class]: Unsatisfied dependency expressed through method 'taskBatchExecutionListener' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration': Invocation of init method failed; nested exception is java.lang.IllegalStateException: To use the default TaskConfigurer the context must contain no more than one DataSource, found 2
                at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
                at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)

【问题讨论】:

  • 根据例外情况,您是否创建了TaskConfigurer
  • (错误地留下不完整的编辑),将 TaskConfigurer 添加到“第二个”数据源,但随后出现异常(可能是因为它似乎正在混合数据源,这应该由应用程序使用 [for read/ write] 作为 Spring Batch 用于写入元数据的一个 -> 原因:org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; 错误的 SQL 语法 [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]; 嵌套异常是java.sql.SQLSyntaxErrorException: 表 'secondarydf.batch_job_instance' 不存在。
  • 我需要查看代码才能提供帮助...
  • 将示例项目添加到github.com/jobas2007/spring_proj
  • 已经找到了一个似乎可行的多次迭代的解决方案,最新的代码已提交到 github。仍然不确定解决方案是否非常干净,因为可以避免一些额外的代码。请提供任何重构或改进的建议?

标签: spring-batch spring-cloud-task


【解决方案1】:

发生错误Table 'secondarydf.batch_job_instance' doesn't exist. 是因为默认情况下,Spring Batch 将使用带有@Primary 注释的dataSource bean,而不是您所期望的getBatchDataSource bean。

来自@EnableBatchProcessing注解的Javadoc

如果上下文中定义了多个 DataSource,则使用 Primary 注解的那个

相关问题是BATCH-2537。因此,在您的情况下,您可以使您的类 BatchConfig 扩展 DefaultBatchConfigurer 并用您要用于批处理的类覆盖 setDataSource

【讨论】:

  • 谢谢。尝试添加 BatchConfigurer 覆盖仍然应用程序模式中的所有表,github 链接发布在以前的项目中。如果时间允许,请克隆项目 BatchConfigurer configurer(@Qualifier("batchDataSource") DataSource dataSource) { return new DefaultBatchConfigurer(batchDataSource()); }
  • 通过一些调整使其工作,感谢您的建议/帮助。代码更新到github,也请看前几篇新增的cmets。现在尝试连接到 Oracle 11.2 的后续步骤,其中 Spring Boot 2.x 的 flyway 依赖性导致问题。将继续发布
  • 仍然面临能够将 Spring Task Project(带有 2 个数据源)与 Spring Cloud DataFlow 一起使用的问题,因为“Task”的执行不会触发底层配置的批处理作业。将相同的内容发布到 spring github github.com/spring-cloud/spring-cloud-task/issues/594 .
  • 当使用 2 个数据源时(一个用于 spring 元数据,第二个用于应用程序)面临“最终”保存/提交到应用程序数据源的间歇性问题。根据其他一些帖子 stackoverflow.com/questions/25540502/… ,建议使用 "ChainedTransactionManager" ,是否有人有示例或任何其他建议(因为似乎两个单独的 tx 上下文正在运行,导致不可预测的行为)?
猜你喜欢
  • 2018-08-30
  • 2018-08-31
  • 2016-04-25
  • 2015-11-03
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
相关资源
最近更新 更多