LoginSignup
4

More than 5 years have passed since last update.

MyBatisのConfigurationでBeanCurrentlyInCreationExceptionが発生しないようにする

Posted at

現象

Spring Boot + MyBatis-Spring を使用している時に BeanCurrentlyInCreationException が発生することがあります。

https://github.com/mybatis/spring/issues/58 でも報告されていて、なにやら修正もされているっぽいのですが、mybatis-spring の 1.2.3 では、まだ取り込まれていない(1.2.3の当該箇所)ようです。1.2.4-SNAPSHOT や 1.3.0-SNAPSHOT には取り込まれているようです。

調査

何パターンかためしたところ@MapperScanMapperScannerConfigurerで使用する SqlSessionFactory を指定した場合に発生するようです。
どうやらMapperFactoryBeanのAutowired設定の有無によって、なぜか DataSource の準備前に Mapper を作ろうとしてしまうようです。

回避策

SqlSessionFactory の生成時に確実に DataSource が作られているようにすることで、上記の問題を回避しました。
具体的には、以下のように SqlSessionFactory とおなじ Configuration 内で DataSource の生成メソッドも用意して、Autowired は使用せずに SqlSessionFactory に設定します。

@Configuration
@MapperScan(value = "xxxx.repository", 
            sqlSessionFactoryRef="sqlSessionFactory")
public class MyBatisConfiguraiton {
    @Bean
    public SqlSessionFactory sqlSessionFactory() {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource());
        ...
        return factory.getObject();
    }

    @Bean
    @ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
}

その他

接続先の DataSource が1つしか無い場合は SqlSessionFactory を明示的に指定する必要は無いので警告がでることも無いかと思います。以下のように設定すれば十分かと思います。

@Configuration
@MapperScan(value = "xxxx.repository")
public class MyBatisConfiguraiton {
    @Autowired
    private DataSource dataSource;

    @Bean
    public SqlSessionFactory sqlSessionFactory() {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        ...
        return factory.getObject();
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4