Spring Boot 多个数据库:没有 EntityManagerFactoryBuilder 类型的合格 bean [英] Spring Boot Multiple Databse : No qualifying bean of type EntityManagerFactoryBuilder
问题描述
我们的 Spring Boot 应用程序中有两个数据库,称为源和目标.这是那些的配置
We have two databases in our Spring Boot Application called source and target. Here is the configuration for those
源配置
package com.alex.myapp.config;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "sourceManagerFactory",
transactionManagerRef = "sourceTransactionManager",
basePackages = {"com.alex.myapp.source.repository"}
)
public class SourceDbConfiguration {
@Autowired
private Environment env;
@Primary
@Bean(name = "sourceManagerFactory")
public LocalContainerEntityManagerFactoryBean
sourceManagerFactory(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean em = builder
.dataSource(sourceDataSource())
.packages("com.alex.myapp.source.entity")
.persistenceUnit("source")
.build();
return em;
}
@Primary
@Bean
public DataSource sourceDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("spring.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
@Primary
@Bean(name = "sourceTransactionManager")
public PlatformTransactionManager sourceTransactionManager(
@Qualifier("sourceManagerFactory") EntityManagerFactory
sourceManagerFactory
) {
return new JpaTransactionManager(sourceManagerFactory);
}
}
目标配置
package com.alex.myapp.config;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "targetManagerFactory",
transactionManagerRef = "targetTransactionManager",
basePackages = {"com.alex.myapp.target.repository"}
)
public class TargetDbConfiguration {
@Autowired
private Environment env;
@Primary
@Bean(name = "targetManagerFactory")
public LocalContainerEntityManagerFactoryBean
targetManagerFactory(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean em = builder
.dataSource(targetDataSource())
.packages("com.alex.myapp.target.entity")
.persistenceUnit("target")
.build();
return em;
}
@Primary
@Bean
public DataSource targetDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("target.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("target.datasource.url"));
dataSource.setUsername(env.getProperty("target.datasource.username"));
dataSource.setPassword(env.getProperty("target.datasource.password"));
return dataSource;
}
@Bean(name = "targetTransactionManager")
public PlatformTransactionManager targetTransactionManager(
@Qualifier("targetManagerFactory") EntityManagerFactory
targetManagerFactory) {
return new JpaTransactionManager(targetManagerFactory);
}
}
当我尝试启动服务器时,它会抛出下面提到的错误
When I try to start server it throws below mentioned error
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-09-19 13:30:53 - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sourceManagerFactory' defined in class path resource [com/alex/myapp/config/SourceDbConfiguration.class]: Unsatisfied dependency expressed through method 'sourceManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:732)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:474)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
如果我注释掉目标配置的类级别注释,一切正常.似乎两个数据库配置相互冲突.
Jut in case if I comment out target configuration's class level annotation everything works fine. It seems both Database Configurations are conflicting with each other.
推荐答案
@Primary
必须完全用于所需类型中的一个 bean.
@Primary
must be used exactly on one bean among the required types.
表示当多个候选者有资格自动装配单值依赖项时,应该优先考虑一个 bean.如果候选中恰好存在一个主要"bean,它将是自动装配的值.
Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.
这篇关于Spring Boot 多个数据库:没有 EntityManagerFactoryBuilder 类型的合格 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!