Peter Penzov
Peter Penzov

Reputation: 1648

No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean found among candidates:

I want to configure Spring Boot to use 2 JNDI datasources. I tried this configuration:

application.properties

spring.production-datasource.jndi-name=java:/global/production_gateway
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update

spring.warehouse-datasource.jndi-name=java:/global/production_warehouse
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update

primary database

@Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.production.entity", 
        entityManagerFactoryRef = "productionEntityManager", 
        transactionManagerRef = "productionTransactionManager"
    )
@EnableTransactionManagement
public class ContextProductionDatasource {

    @Autowired
    private Environment env;

    @Primary
    @Bean
    @ConfigurationProperties(prefix="spring.production-datasource")
    public DataSource productionDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean   
    public EntityManager productionEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

    @Primary
    @Bean
    public PlatformTransactionManager productionTransactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Primary
    @Bean
    public PersistenceExceptionTranslationPostProcessor productionExceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

second datasource:

@Configuration
@EnableJpaRepositories(
        basePackages = "org.datalis.plugin.warehouse.entity", 
        entityManagerFactoryRef = "warehouseEntityManager", 
        transactionManagerRef = "warehouseTransactionManager"
    )
@EnableTransactionManagement
public class ContextWarehouseDatasource {

    @Autowired
    private Environment env;

    @Primary
    @Bean
    @ConfigurationProperties(prefix="spring.warehouse-datasource")
    public DataSource warehouseDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean   
    public EntityManager warehouseEntityManager(EntityManagerFactory emf) {
        return emf.createEntityManager();
    }

    @Bean
    public PlatformTransactionManager warehouseTransactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor warehouseExceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

When I deploy the code I get exception:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean found among candidates: [productio                     nDataSource, warehouseDataSource]"}}

Full error stack:

https://pastebin.com/EsNp2Fp9

Do you know how I can solve this issue?

Upvotes: 0

Views: 9728

Answers (1)

MyTwoCents
MyTwoCents

Reputation: 7624

You can have only 1 primary Datasource. Other confuguration looks fine.

Assuming ContextWarehouseDatasource as secondary connection

Remove @Primary from warehouseDataSource() like this and try.

@Bean
@ConfigurationProperties(prefix="spring.warehouse-datasource")
public DataSource warehouseDataSource() {
    return DataSourceBuilder.create().build();
}

Upvotes: 7

Related Questions