Spring with MyBatis: expected single matching bean but found 2

Alex Woolford

I've been using Spring with MyBatis and it's been working really well for a single database. I ran into difficulties when trying to add another database (see reproducible example on Github).

I'm using Spring Java configuration (i.e. not XML). Most of the examples I've seen show how to achieve this using XML.

I have two data configuration classes (A & B) like this:

@Configuration
@MapperScan("io.woolford.database.mapper")
public class DataConfigDatabaseA {

    @Bean(name="dataSourceA")
    public DataSource dataSourceA() throws SQLException {
        SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriver(new com.mysql.jdbc.Driver());
        dataSource.setUrl("jdbc:mysql://" + dbHostA + "/" + dbDatabaseA);
        dataSource.setUsername(dbUserA);
        dataSource.setPassword(dbPasswordA);
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSourceA());
        return sessionFactory.getObject();
    }
}

Two mappers, and a service that autowires the mappers:

@Service
public class DbService {

    @Autowired
    private DbMapperA dbMapperA;

    @Autowired
    private DbMapperB dbMapperB;

    public List<Record> getDabaseARecords(){
        return dbMapperA.getDatabaseARecords();
    }

    public List<Record> getDabaseBRecords(){
        return dbMapperB.getDatabaseBRecords();
    }

}

The application won't start:

Error creating bean with name 'dataSourceInitializer': 
  Invocation of init method failed; nested exception is 
    org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
      No qualifying bean of type [javax.sql.DataSource] is defined: 
        expected single matching bean but found 2: dataSourceB,dataSourceA

I've read that it's possible to use the @Qualifier annotation to disambiguate the autowiring, though I wasn't sure where to add it.

Can you see where I'm going wrong?

Alex Woolford

In the end, we put each mapper in its own folder:

src/main/java/io/woolford/database/mapper/a/DbMapperA.java
src/main/java/io/woolford/database/mapper/c/DbMapperB.java

We then created two DataConfig classes, one for each database. The @MapperScan annotation resolved the expected single matching bean but found 2 issue.

@Configuration
@MapperScan(value = {"io.woolford.database.mapper.a"}, sqlSessionFactoryRef="sqlSessionFactoryA")
public class DataConfigDatabaseA {

It was necessary to add the @Primary annotation to the beans in one of the DataConfig classes:

@Bean(name="dataSourceA")
@Primary
public DataSource dataSourceA() throws SQLException {
    ...
}

@Bean(name="sqlSessionFactoryA")
@Primary
public SqlSessionFactory sqlSessionFactoryA() throws Exception {
    ...
}

Thanks to everyone who helped. No doubt, there's more than one way to do this. I did try @Qualifier and @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) as recommended by @eduardlofitskyi and @GeminiKeith, but that generated some further errors.

In case it's useful, the solution that worked for us is posted here: https://github.com/alexwoolford/mybatis-spring-multiple-mysql-reproducible-example

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

No qualifying bean, expected single matching bean but found 2

class required a single bean, but 2 were found:

SpringBoot : No matching bean found exception

No qualifying bean of type 'javax.persistence.EntityManager' available: expected single matching bean but found 2

NoUniqueBeanDefinitionException: no qualifying bean of type ... i defined, expected single matching bean but found 2

No matching bean of type ... found for dependency

SpringFramework: expected single matching bean but found 2

Field restTemplate required a single bean, but 2 were found

Spring Bean Not Found

Spring boot Keep getting "required a single bean, but 10 were found" although I declared only one service

Spring MVC AuthenticationManager expected single matching bean but found 4

Required Single bean but 2 were found even when referenced in Spring config

Spring boot app failed to start with error "Application required a single bean, but 2 were found"

NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean

Spring Security Java - Multiple Authentication Manager - 2 bean found error

Expected one matching request for criteria "Match URL" - None found - Angular2+

getting error No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2

No matching handler method found - Spring

Spring FactoryBean and autowiring not working : expected single matching bean but found 2

No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0:

No qualifying bean of type found for dependency in Spring Boot single table

Parameter 0 of method standardParameterResolver ... required a single bean, but 2 were found

Spring xml configuration: No unique bean found: expected 1 but found 0

Spring Boot Embedded Tomcat - No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 3

No qualifying bean of type 'org.springframework.batch.core.Job' available: expected single matching bean but found 2:

Expected one matching request, found 2 requests. How do I test for 2 requests

No signatures found matching the expected signature for payload

Spring RequestScope bean not working as expected

Parameter 'status' not found. Available parameters are [0, 1, param1, param2] in Mybatis and Spring