Search code examples
springmybatisspring-mybatismappers

MyBatis+Spring MapperScan with Mulitple Data Sources


I am pulling data from two different databases using MyBatis 3.3.1 and Spring 4.3. The two configuration classes to scan for mappers look at follows:

    @Configuration  
    @MapperScan(value="com.mapper1.map",   
   SqlSessionFactoryRef="sqlSessionFactory1")
   public class AppConfig {
    @Bean
    public DataSource getDataSource1() {
       BasicDataSource dataSource = new BasicDataSource();
       dataSource.setDriverClassName("com.mysql.jdbc.Driver");
       dataSource.setUrl("jdbc:mysql://localhost:3306/database1");
       dataSource.setUsername("user");
       dataSource.setPassword("pw");
       return dataSource;
   }
   @Bean
   public DataSourceTransactionManager transactionManager1() {
       return new DataSourceTransactionManager(getDataSource1());
   }
   @Bean
   public SqlSessionFactory sqlSessionFactory1() throws Exception {
      SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
      sessionFactory.setDataSource(getDataSource1());
      return sessionFactory.getObject();
   }
} 

    @Configuration
   @MapperScan(value="com.mapper2.map",   
   SqlSessionFactoryRef="sqlSessionFactory2")
   public class AppConfig {
    @Bean
    public DataSource getDataSource2() {
       BasicDataSource dataSource = new BasicDataSource();
       dataSource.setDriverClassName("com.mysql.jdbc.Driver");
       dataSource.setUrl("jdbc:mysql://localhost:3307/database2");
       dataSource.setUsername("user");
       dataSource.setPassword("pw");
       return dataSource;
   }
   @Bean
   public DataSourceTransactionManager transactionManager2() {
       return new DataSourceTransactionManager(getDataSource2());
   }
   @Bean
   public SqlSessionFactory sqlSessionFactory2() throws Exception {
      SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
      sessionFactory.setDataSource(getDataSource2());
      return sessionFactory.getObject();
   }
} 

The code deploys fine, but only mappers from data source 1 works. When I try to use a mapper from data source 2, I get a "No table found" exception from my database. The problem is that although I am setting the specific SqlSessionFactory that I want to use in the mapperScan, it ends up using the other SqlSessionFactory for all the mappers. If I comment out the SqlSessionFactory in configuration 1, then Configuration 2 will work.

Note that if I don't use MapperScan, but instead use a MapperScannerConfigurer bean, I am able to correctly retrieve data.

Has anyone else had problems using @MapperScan with multiple data sources?


Solution

  • The only issue I see in your code is SqlSessionFactoryRef should be from lowercase: (sqlSessionFactory). Apart from that everything is fine, this approach works for me.

    You can also look at ace-mybatis. It allows to work with multiple datasources configuring only one bean.