Project based on Spring boot and batch. I need to use h2 database for storing metadata for spring batch tables and postgre for Spring JPA(Used by ItemWriter).
I have defined two separate properties in properties file.
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
Now, In @configuration file in order to link batch datasource I defined,
@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);
}
However, I didn't used another jpa(postgre) db configuration anywhere else,(planning to link it with JPA).
When I am trying to run the project, i am getting below exception.
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$doGetBean0ドル(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda189ドル.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$doGetBean0ドル(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda189ドル.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]
What the issue? I didnt declare any other datasource so that spring boot start creating one. Also, How can I decalre the postgre datasource such that it can be used by jpa for interation with DB.
Sorry, if this question sound very basic, I am noob in spring.
Added 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);
}
}
-
@KavithakaranKanapathippillai Added aboveNikhil Kumar– Nikhil Kumar2020年07月02日 07:55:02 +00:00Commented Jul 2, 2020 at 7:55
1 Answer 1
Error creating bean with name 'dataSourceBatch': Requested bean is currently in creation
You are injecting the data source (which is being created) in the batch configurer here:
@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);
}
Try to move data source configuration in another class:
@Configuration
public class DataSourceConfiguration {
@Primary
@ConfigurationProperties(prefix="batch.datasource")
@Bean(name="dataSourceBatch")
public DataSource firstDataSource() {
DataSource ds = DataSourceBuilder.create().build();
return ds;
}
}
Then import it in your batch configuration class:
@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
}
Note also how I removed field injection of jobBuilderFactory and stepBuilderFactory and replaced it with constructor injection.
Comments
Explore related questions
See similar questions with these tags.