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

带JPA的Spring Boot批处理动态多数据源

吕淮晨
2023-03-14

基于Spring boot和batch的项目。我需要使用h2数据库来存储spring批处理表的元数据,以及spring JPA的postgre(由ItemWriter使用)。

我在属性文件中定义了两个独立的属性。

postgres.datasource.url=jdbc:postgresql://urlxxx
postgres.datasource.username=xxx
postgres.datasource.password=yyy

batch.datasource.url=jdbc:h2:mem:testdb
batch.datasource.driverClassName=org.h2.Driver
batch.datasource.username=xxx2
batch.datasource.password=yyy2

现在,在@配置文件中,为了链接我定义的批处理数据源,

@Primary
@ConfigurationProperties(prefix="batch.datasource")
@Bean(name="dataSourceBatch")
public DataSource firstDataSource() {
    DataSource ds =  DataSourceBuilder.create().build();
    return ds;
}

@Bean
  BatchConfigurer configurer(@Qualifier("dataSourceBatch") DataSource dataSource){
    return new DefaultBatchConfigurer(dataSource);
  }

但是,我没有在其他任何地方使用另一个jpa(postgre)db配置(计划将其与JPA链接)。

当我试图运行的项目,我得到下面的异常。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'batchConfig': Unsatisfied dependency expressed through field 'jobBuilderFactory'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration': Unsatisfied dependency expressed through field 'dataSource'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dataSourceBatch': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$189.0000000010E4E030.getObject(Unknown Source) ~[na:na]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:408) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$189.0000000010E4E030.getObject(Unknown Source) ~[na:na]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]

什么问题?我没有声明任何其他数据源,所以spring boot开始创建一个。此外,我如何对postgre数据源进行贴标,以便jpa可以使用它与DB进行交互。

抱歉,如果这个问题听起来很基本,我是Spring的noob。

添加了batchconfig

@Configuration
@EnableScheduling
public class BatchConfig {
        @Autowired
        private JobBuilderFactory jobBuilderFactory;

        @Autowired
        private StepBuilderFactory stepBuilderFactory;

     
        @Bean
        ItemReader<ABC> reader() {
            return new LocationReader();
        }
        
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }

        @Bean
        ItemProcessor<ABC,ABC> moviesItemProcessor() {
            return new LocationProcessor();
        }

        @Bean
        ItemWriter<ABC> Writer(){

            return new LocationWriter();
            
        }


        @Bean
        public Step step1(ItemReader<ABC> reader,
                            ItemProcessor<ABC,ABC> processor,
                            ItemWriter<ABC> writer) throws Exception {
            return stepBuilderFactory.get("step1")
                    .<ABC, ABC>chunk(10)
                    .reader(reader)
                    .processor(processor)
                    .writer(writer).allowStartIfComplete(true)
                    .build();
        }

        @Bean
        public Job job(Step step1) throws Exception {
            return jobBuilderFactory.get("job")
                    .start(step1(reader(), moviesItemProcessor(), Writer()))
                    .build();
        }
        
        
        
        
        @Primary
        @ConfigurationProperties(prefix="batch.datasource")
        @Bean(name="dataSourceBatch")
        public DataSource firstDataSource() {
            DataSource ds =  DataSourceBuilder.create().build();
            return ds;
        }
       
          @Bean
          BatchConfigurer configurer(@Qualifier("dataSourceBatch") DataSource dataSource){
            return new DefaultBatchConfigurer(dataSource);
          }

        
//
//      @Bean
//      public JobRepository jobRepository() throws Exception {
//          final JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
//          factory.setDatabaseType(DatabaseType.H2.getProductName());
//          factory.setDataSource(firstDataSource());
//          return factory.getObject();
//      }
//
//      @Bean
//      public SimpleJobLauncher jobLauncher() throws Exception {
//          final SimpleJobLauncher launcher = new SimpleJobLauncher();
//          launcher.setJobRepository(jobRepository());
//          return launcher;
//      }
        

        @Autowired
        JobLauncher jol;

        
        @Autowired
        Job job;
         
        
        @Scheduled(cron = "0 */1 * * * ?")
        public void perform() throws Exception 
        {
            JobParameters params = new JobParametersBuilder()
                    .addString("JobID", String.valueOf(System.currentTimeMillis()))
                    .toJobParameters();
            jol.run(job, params);
        }

}

共有1个答案

昝晗昱
2023-03-14

创建名为“dataSourceBatch”的bean时出错:请求的bean当前正在创建中

您将在此处的批处理配置程序中注入数据源(正在创建):

@Primary
@ConfigurationProperties(prefix="batch.datasource")
@Bean(name="dataSourceBatch")
public DataSource firstDataSource() {
   DataSource ds =  DataSourceBuilder.create().build();
   return ds;
}

@Bean
BatchConfigurer configurer(@Qualifier("dataSourceBatch") DataSource dataSource){
   return new DefaultBatchConfigurer(dataSource);
}

尝试在另一个类中移动数据源配置:

@Configuration
public class DataSourceConfiguration {

   @Primary
   @ConfigurationProperties(prefix="batch.datasource")
   @Bean(name="dataSourceBatch")
   public DataSource firstDataSource() {
      DataSource ds =  DataSourceBuilder.create().build();
      return ds;
   }

}

然后将其导入批处理配置类:

@Configuration
@EnableScheduling
@Import({DataSourceConfiguration.class})
public class BatchConfig {

   private JobBuilderFactory jobBuilderFactory;
   private StepBuilderFactory stepBuilderFactory;

   public BatchConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
       this.jobBuilderFactory = jobBuilderFactory;
       this.stepBuilderFactory = stepBuilderFactory;
   }


   @Bean
   BatchConfigurer configurer(@Qualifier("dataSourceBatch") DataSource dataSource){
      return new DefaultBatchConfigurer(dataSource);
   }

   // the rest of you config

}

另请注意我如何删除jobBuilderFactorystepBuilderFactory的字段注入并将其替换为构造函数注入。

 类似资料:
  • 我正在编写Spring批的Spring Boot应用程序,其中ItemReader从Oracle数据库读取数据并将数据写入postgres sql,但我得到了以下错误 我不想创建spring批处理元数据表,我的应用程序不需要监视作业,请就此向我提出建议。提前谢谢!!

  • 我需要访问两个数据源: Spring批处理存储库:在内存H2中 我的步骤需要访问。 我在那里看到了几个关于如何创建自定义

  • 我使用的是Spring Batch 2.1.8。释放我有一个文件,它由一些头信息和一些需要处理的记录组成。 我有一个使用面向块处理的步骤。该步骤包含ItemReader和ItemWriter的实现。ItemReader实现是线程安全的,而ItemWriter不是。 我想在处理(或写入)任何记录之前使用标题信息。在继续使用面向块的处理时,如何确保这一点? 建议的解决方案:一种解决方案可以是编写一个预

  • 我试图在Spring批处理中配置几个数据源。启动时,Spring批处理抛出以下异常: 批处理配置的代码段 不知道为什么我会看到这个异常,因为我看到了一些基于xml的Spring批处理配置,这些配置声明了多个数据源。我使用的是Spring批处理核心版本3.0.1.发行版和Spring Boot版本1.1.5.发行版。如有任何帮助,将不胜感激。

  • 我的数据库中有大约1000万个blob格式的文件,我需要转换并以pdf格式保存它们。每个文件大小约为0.5-10mb,组合文件大小约为20 TB。我正在尝试使用spring批处理实现该功能。然而,我的问题是,当我运行批处理时,服务器内存是否可以容纳那么多的数据?我正在尝试使用基于块的处理和线程池任务执行器。请建议运行作业的最佳方法是否可以在更短的时间内处理如此多的数据

  • 批处理配置具有spring作业,只有一个步骤 1)读取器-从csv文件读取。处理器对文件应用一些规则。Drools请运行schema-postgresql.sql来设置数据库 WRITER使用SPRING DATA JPA写入DB Writer将此称为PersonDaoImpl: