こんにちは、エキサイト株式会社の平石です。
私の担当するサービスでは、Spring Boot (Java)を利用していますが、ローカルではFlyway + MyBatis GeneratorでDB環境および、JavaからDBへの接続環境を構築しています。
その際、複数のデータベースに接続しようとすると、生成されるMapper名(Bean扱い)が重複してしまい、エラーになってしまいました。
その問題の解決方法を紹介したいと思います。
FlywayとMyBatis Generatorについて
Flywayはデータベースマイグレーションツール、MyBatis GeneratorはDB内のテーブルからModel(Entity)やMapperを自動生成してくれるツールです。 生成したModelやMapperを利用して対応するテーブルにJavaからアクセスすることができます。
- SQLファイルにテーブル作成や変更のSQLを記述
- Flywayを利用して、マイグレーション
- MyBatis Generatorを利用して、マイグレーションで生成されたテーブルからModelやMapperを生成
ここでは、それぞれの仕組みや導入方法の詳細は紹介しませんので、以下の記事をご覧ください。
生成されたMapper名がコンフリクトする
Flywayでは、デフォルトではflyway_schema_history
という名前のテーブルでマイグレーションの履歴を管理しています。
私が担当するプロジェクトでは2つのデータベースにアクセスする必要があり、以下のブログ内の方法で設定しました。
この時、この2つのデータベースはFlyway + MyBatis Generatorで環境設定を行なっており、それぞれのデータベースにflyway_schema_history
というテーブルが存在することになります。
この状況で、MyBatis Generatorを実行するとFlywaySchemaHistoryMapper
というMapperが2つ生成されてしまいます。
MapperはBeanの扱いとなるため、この状況でSpring Bootアプリケーションを起動すると、同じ名前のBeanが複数あることになりエラーが発生します。
2024-01-21T13:57:45.841+09:00 ERROR 80082 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'flywaySchemaHistoryMapper' for bean class [com.example.sample_project.persistence.schema2.mappergen.FlywaySchemaHistoryMapper] conflicts with existing, non-compatible bean definition of same name and class [org.mybatis.spring.mapper.MapperFactoryBean]
私の調べた限りでは、特定のテーブル(ここでは、flyway_schema_history
)のみ生成対象からを除外することはできないようです。
また、以下のブログで紹介されている方法をうまく利用すれば回避できそうですが、全てのEntityやMapperにSuffixやPrefixがついてしまうためあまり実行したくありません。
historyテーブルの名前を変更する
色々と調べていますと、どうやらマイグレーションの履歴を管理するテーブルの名前を変更することができるようです。
Table - Flyway - Product Documentation
Flywayの設定の方法は複数ありますが、設定ファイルを利用する場合は以下のような内容を記述することになります。
Configuration - Flyway - Product Documentation
〜〜urlやuser, passwordの情報が記述されている〜〜 flyway.table=schema1_flyway_schema_history
これで、マイグレーションの履歴を管理するテーブルの名前がschema1_flyway_schema_history
になり、生成されるMapperの名前が重複しないようになりました。
(今回は、マイグレーションの履歴テーブルのMapperファイルという、実際には不要なBeanの名前被りが原因のエラーでした。しかし、複数のデータベースに同じ名前のテーブルが多く存在してしまうことが原因の場合には、Suffixのように名前被りを排除するような設定する必要があります。)
終わりに
今回は、FlywayとMyBatis Generatorを利用しており、複数のデータベースに接続する必要がある場合に発生するエラーとその対処法を紹介しました。
最も綺麗な方法は、特定のテーブルを生成対象から除外する設定を追加してくれることですので、MyBatis Generatorがその対応をしてくれると良いですね。
では、また次回。