スターエンジニアになりたい

異世界転生を待って早10年

DbUnit AmbiguousTableNameExceptionが発生 #9

こんにちは hkrblog です.
DbUnit使用時にエンカウントしたAmbiguousTableNameExceptionを解決したので
それを記していきたいと思います.
若干日が経っちゃってちょい曖昧気味...

状況整理 / 原因

まず自分の場合は、SpringBoot, DBはPostgreSQLですね.
状況としては、
* データベース内に同名のテーブルが存在してる
(つまり別スキーマに同名のテーブルが存在している)

基本的にはこの状況だと思います.
自分の場合は厄介だったのが、VIEW(ビュー)を作成していたということですね.
これ全然関係なくて、DbUnitは普通にテーブルを探しに行くのでビューは関係なし.
初動でもしかしてビューか!?と疑ったので若干時間無駄にしました.
話を戻すと原因は上記の同名のテーブルが存在しているということ.
DbUnitは内部でテーブル名をマップ(確か)に詰めていくんだけれども、
そこで同名のテーブルがくるとAmbiguousTableNameExceptionを発生させる.
(だった気がした..)

なので、どのschemaのどのtableなのか?をハッキリさせれば良い.
で自分の場合はエラー表示されるテーブル名が大文字だったのも気になった.
これ関係あったんだかなかったんだか忘れちゃったんだけど、
小文字のはずのテーブル名が大文字で認識できるはずはないということでその辺も設定をしました.


実施した解決方法

1. Configuration
@Configuration
public class DbUnitConfig {

    @Value("${dbunit.schema.name}")
    private String schema;

    @Bean
    public DatabaseConfigBean dbUnitDatabaseConfig() {
        DatabaseConfigBean bean = new DatabaseConfigBean();
        bean.setQualifiedTableNames(true);
        bean.setCaseSensitiveTableNames(true);
        return bean;
    }

    @Bean
    public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(
                     DataSource dataSource, DatabaseConfigBean dbUnitDatabaseConfig ) {
        DatabaseDataSourceConnectionFactoryBean bean = 
                     new DatabaseDataSourceConnectionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setDatabaseConfig(dbUnitDatabaseConfig);
        bean.setSchema(schema);
        return bean;
    }

}

設定クラスはこんな感じ.(インデントとかの関係で見づらくなってたらすみません)
DatabaseConfigBeanの登録で大文字小文字の区別したりという感じで、
DatabaseDataSourceConnectionFactoryBeanでスキーマ名をセットしてあげてます.

2. ファイル名

あとは読み込むCSVファイルの名前をスキーマ名.テーブル名.csvに変更する
テストデータを入力したcsvファイルの名前を例えば,
myschemaのmytableにデータを投入したいなら(myschemaは上のクラスでセットしたschema名)
名前は、myschema.mytable.csv にします.


あとは実際に実行してみてください.
できましたね? ...ね!?ね!?

PostgresはOK!!この勢いで
Oracleも余裕じゃ~(Oracleも使用している)と思ったらNoSuchTableExceptionが発生して
発狂しかけたので次回はDbUnitの NoSuchTableExceptionの解決記事にしようかなと思います.

もしかしたらKotlin記事になるかもです...

それではまた次回にお会いしましょう~~~~~.