SheppardDigital
SheppardDigital

Reputation: 3255

Spring Boot, required a single bean, but 2 were found when creating multiple datasources

I have an application in Spring Boot 1.4 which I'm trying to add additional datasources to.

First I setup a primary datasource and ran the application to check it still worked, and it did. Then I went ahead and added a second datasource, but when I did that I got the following error;

Description:

Field userRepo in com.nationallocums.config.CustomUserDetailsService required a single bean, but 2 were found:
    - nlDoctorsEntityManager: defined by method 'nlDoctorsEntityManager' in class path resource [com/nationallocums/config/NLDoctorsDataSourceConfiguration.class]
    - primaryEntityManager: defined by method 'primaryEntityManager' in class path resource [com/nationallocums/config/PrimaryDataSourceConfiguration.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

I don't understand why I'm seeing this error, as I've clearly marked one of the datasources with @Primary, but it seems Spring Boot isn't picking that up.

Here's my two datasource configurations;

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "primaryEntityManager",
        transactionManagerRef = "primaryTransactionManager",
        basePackages = { "com.nationallocums.repository" })
@EnableTransactionManagement
public class PrimaryDataSourceConfiguration {

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

    @Bean(name = "primaryEntityManager")
    @Primary
    public LocalContainerEntityManagerFactoryBean primaryEntityManager(final EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") final DataSource dataSource) {
        final Map<String, String> properties = new HashMap<>();
        return builder
                .dataSource(dataSource)
                .properties(properties)
                .packages("com.nationallocums.model")
                .persistenceUnit("primary")
                .build();
    }

    @Bean(name = "primaryTransactionManager")
    @Primary
    public PlatformTransactionManager nlDoctorsTransactionManager(@Qualifier("primaryEntityManager") final EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

and...

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "nlDoctorsEntityManager",
        transactionManagerRef = "nlDoctorsTransactionManager",
        basePackages = { "com.nationallocums.eclipse.nldoctorsrepository" })
@EnableTransactionManagement
public class NLDoctorsDataSourceConfiguration {

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

    @Bean(name = "nlDoctorsEntityManager")
    public LocalContainerEntityManagerFactoryBean nlDoctorsEntityManager(final EntityManagerFactoryBuilder builder, @Qualifier("nlDoctorsDataSource") final DataSource dataSource) {
        final Map<String, String> properties = new HashMap<>();
        return builder
                .dataSource(dataSource)
                .properties(properties)
                .packages("com.nationallocums.eclipse.model")
                .persistenceUnit("nlDoctors")
                .build();
    }

    @Bean(name = "nlDoctorsTransactionManager")
    public PlatformTransactionManager nlDoctorsTransactionManager(@Qualifier("nlDoctorsEntityManager") final EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

Can anyone spot what I've done wrong?

Upvotes: 0

Views: 1967

Answers (1)

SheppardDigital
SheppardDigital

Reputation: 3255

I managed to fix this by changing my repository from...

@PersistenceContext
private EntityManager entityManager;

to...

@Autowired
@Qualifier("primaryDataSource")
private EntityManager entityManager;

Upvotes: 1

Related Questions