Exception 资源注释:未定义[javax.sql.DataSource]类型的合格bean:应为单个匹配bean,但找到2个

Exception 资源注释:未定义[javax.sql.DataSource]类型的合格bean:应为单个匹配bean,但找到2个,exception,dependency-injection,spring-data,Exception,Dependency Injection,Spring Data,我使用基于SpringJava的配置来配置带有Spring数据的多个数据库。 在配置文件中,我为MySQL和MSSQL服务器创建了两个数据源。尝试使用@Resource注释将依赖项注入实体管理器时,我遇到以下异常: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected sing

我使用基于SpringJava的配置来配置带有Spring数据的多个数据库。 在配置文件中,我为
MySQL
MSSQL服务器创建了两个
数据源
。尝试使用
@Resource
注释将依赖项注入实体管理器时,我遇到以下异常:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: mysql_datasource,secure_datasource
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1016)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:815)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:743)
以下是我的代码:

@Bean(name="secure_datasource")
public DataSource dataSource(){
    try{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl(environment.getProperty("sc.db.url"));
        dataSource.setDriverClass(environment.getProperty("sc.db.driver.class"));
        dataSource.setUser(environment.getProperty("sc.db.username"));
        dataSource.setPassword(environment.getProperty("sc.db.password"));
        dataSource.setIdleConnectionTestPeriod(60);
        dataSource.setMaxPoolSize(10);
        dataSource.setMaxStatements(7);
        dataSource.setMinPoolSize(1);
        return dataSource; 
    }catch(Exception ex){
        throw new RuntimeException(ex);
    }
}

.................

@Bean(name="mysql_datasource")
public DataSource dataSource(){
    try{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl(environment.getProperty("db.url"));
        dataSource.setDriverClass(environment.getProperty("db.driver.class"));
        dataSource.setUser(environment.getProperty("db.username"));
        dataSource.setPassword(environment.getProperty("db.password"));
        dataSource.setIdleConnectionTestPeriod(60);
        dataSource.setMaxPoolSize(100);
        dataSource.setMaxStatements(50);
        dataSource.setMinPoolSize(10);
        return dataSource; 
    }catch(Exception ex){
        throw new RuntimeException(ex);
    }
}

.......

@Resource(value="mysql_datasource")
@Bean(name="entity_manager_factory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource){
    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource);
    factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
    factoryBean.setPackagesToScan(environment.getProperty("package.scan"));
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
    return factoryBean;
}

我还尝试使用
@Qualifier
注释作为我建议的链接,但仍然得到错误

我也遇到了同样的问题,找到了这篇解释这个问题的老帖子:

看起来,如果您需要多个数据源,Spring引导的魔力就会耗尽,您必须手动接管配置

在我的情况下,我必须修改EnableAutoConfiguration以接管数据源和事务管理器配置:

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class}) 

在我不得不使用多个数据源的时候,Spring Boot的魔力似乎已经消失了…

我也遇到了同样的问题,在经历了很多头痛之后,我偶然发现了这个让我感到非常愚蠢的问题:(

您所需要的只是在其中一个数据源上安装@Primary,Spring Boot将不再混乱…这是我的一个配置…其余的配置几乎相同,指向其他数据库,并且没有@Primary在它们上面

@Configuration
@EnableTransactionManagement
@EntityScan(basePackages = {"somepackage.entities"})
@EnableJpaRepositories(entityManagerFactoryRef = "emfDB1", transactionManagerRef = "tmDB1", basePackages = {"somepackage.repositories"})
class PersistenceDB1 {
    @Bean
    @Primary
    DataSource dsDB1() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setUrl("jdbc:mysql://someserver:3306/proativo");
        dataSource.setUsername("username");
        dataSource.setPassword("password");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }

    @Bean
    @Primary
    LocalContainerEntityManagerFactoryBean emfDB1() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dsDB1());
        entityManagerFactoryBean.setJpaVendorAdapter(new EclipseLinkJpaVendorAdapter());

        entityManagerFactoryBean.setPersistenceXmlLocation("classpath:META-INF/DB1-persistence.xml");

        Properties jpaProperties = new Properties();
        jpaProperties.put("eclipselink.weaving", "false");
        jpaProperties.put("eclipselink.logging.level", "SEVERE"); // SEVERE / FINEST

        entityManagerFactoryBean.setJpaProperties(jpaProperties);
        return entityManagerFactoryBean;
    }

    @Bean
    @Primary
    JpaTransactionManager tmDB1() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emfDB1().getNativeEntityManagerFactory());
        return transactionManager;
    }
}
编辑:
忘了提及:可能是由于我配置类的方式,排除@EnableAutoConfiguration上的某些类的方法对我不起作用…

在我的情况下,配置是在xml文件上的,所以我只需添加primary=“true”到其中一个已定义数据源的bean标记。

我添加了@Primary指令,但当我创建事务管理器时,它们的两个会话工厂都使用主数据源。有没有方法专门告诉sessionfactory使用哪个数据源?我们可能需要一些代码来弄清楚,正如您在abov中看到的那样e代码,会话管理器在事务管理器创建时指定。