【发布时间】:2020-03-19 16:45:38
【问题描述】:
我正在尝试在我的 Spring 应用程序中设置第二个数据源。 以下是 2 个数据源的 2 个配置类:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.XYXYale.persistence.XY",
entityManagerFactoryRef = "awEntityManagerFactory",
transactionManagerRef= "awTransactionManager"
)
public class Datasource1DataSourceConfig {
@Value("${spring.first-datasource.url}")
private String url;
@Value("${spring.first-datasource.username}")
private String username;
@Value("${spring.first-datasource.password}")
private String pw;
@Value("${spring.first-datasource.driver-class-name}")
private String driver;
@Bean
@Primary
@ConfigurationProperties("spring.first-datasource")
public DataSourceProperties awDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@Qualifier("awEntityManagerFactory")
public DataSource awDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(pw);
return dataSource;
}
@Primary
@Bean(name = "awEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean awEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(awDataSource());
em.setPersistenceUnitName("XY");
");
em.setPackagesToScan(new String[] { "com.XY.XY.domain.XY" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
@Primary
@Bean
public PlatformTransactionManager awTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
awEntityManagerFactory().getObject());
return transactionManager;
}
}
第二个Config类:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.XYXYale.persistence.YX",
entityManagerFactoryRef = "sndEntityManagerFactory",
transactionManagerRef= "sndTransactionManager"
)
public class SndDataSourceConfig {
@Value("${spring.second-datasource.jdbcUrl}")
private String url;
@Value("${spring.second-datasource.username}")
private String username;
@Value("${spring.second-datasource.password}")
private String pw;
@Value("${spring.second-datasource.driver-class-name}")
private String driver;
@Bean
@ConfigurationProperties("spring.second-datasource")
public DataSourceProperties sndDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Qualifier("sndEntityManagerFactory")
public DataSource sndDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(pw);
return dataSource;
}
@Bean(name = "sndEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean sndEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(sndDataSource());
em.setPersistenceUnitName("snd");
em.setPackagesToScan(new String[] { "com.XY.XY.domain.YX" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
@Bean
public PlatformTransactionManager sndTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
sndEntityManagerFactory().getObject());
return transactionManager;
}
}
我在 com.XYXYale.persistence.XY 中有一个 Spring data JPA Repo 定义如下
演示回购
@Repository
public interface DemoRepo extends CrudRepository<Demo, String>, DemoRepoCustom{
}
DemoRepoCustom
@NoRepositoryBean
public interface DemoRepoCustom {
Demo returnDemoContent();
}
DemoRepoImpl
public class DemoRepoImpl extends QuerydslRepositorySupport implements DemoRepoCustom {
public DemoRepoImpl() {
super(Demo.class);
}
public Demo returnDemoContent(){
return something;
}
}
Repo 的使用方式如下
@Autowired
DemoRepo demoRepo;
我遇到了这个异常:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'demoRepositoryImpl': Unsatisfied dependency expressed through method 'setEntityManager' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected single matching bean but found 2: org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework.orm.jpa.SharedEntityManagerCreator#1
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:678)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:307)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1255)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:595)
... 55 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected single matching bean but found 2: org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework.orm.jpa.SharedEntityManagerCreator#1
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:221)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1233)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:670)
... 70 more
有人对如何解决这个问题有建议吗?我可以考虑为每个 repo 注入正确的 entitymanager,但是我不知道该怎么做。
提前致谢。在此处或其他网站上找不到任何解决方案。
【问题讨论】:
-
@Ramu Nope,已经在这里查看了答案,否则我不会问。
-
您可以尝试使用限定符注解明确指定 bean 名称,因为 spring 正在寻找两个 bean 并且不知道要注入哪个。
-
对不起。你的要求看起来和那个很相似。看看下面的对你有帮助吗? stackoverflow.com/questions/45663025/…
-
谢谢@SB 你有一个例子如何在 spring Config 类以及 repos 的 impl 类中正确实现限定符吗?
标签: java spring hibernate spring-boot jpa