AmbiguousTableNameException

ある日突然テストが動かなくなってしまった。

org.dbunit.database.AmbiguousTableNameException: HOGE_HOGE
 at org.dbunit.database.DatabaseDataSet.initialize(DatabaseDataSet.java:140)
 at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:186)
 at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:98)
 at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:67)


さっそくGoogle先生に調査を依頼する*1
なるほど、スキーマの名前を設定すればよいのか


・・・どうやるねん。

((http://dbunit.sourceforge.net/apidocs/org/dbunit/database/AmbiguousTableNameException.html))
This exception is thrown by DatabaseDataSet when a multiple tables having the same name are accessible. This usually occurs when the database connection have access to multiple schemas containing identical table names.

Possible solutions: 1) Use a database connection credential that has access to only one database schema. 2) Specify a schema name to the DatabaseConnection or DatabaseDataSourceConnection constructor. 3) Enable the qualified table name support (see How-to documentation). 

spring+hibernateなので1)と3)はよく分からないが、DatabaseConnectionのところでなんとかなるだろう。


修正個所は、自作のDbUnitUtilsクラスのgetConnection()とかそのあたり。

IDatabaseConnection con = new DatabaseConnection(session.connection());
 ↓
IDatabaseConnection con = new DatabaseConnection(session.connection(), schemaname);


スキーマ名は要するに接続するユーザ名なので、contextからとってくる。

 //接続先スキーマ名
 private String schemaname;

 public DbUnitUtils() {
  (略)
  org.springframework.jdbc.datasource.DriverManagerDataSource dataSource = (org.springframework.jdbc.datasource.DriverManagerDataSource) context.getBean("dataSource");
  schemaname = dataSource.getUsername().toUpperCase();
 }


しばらく悩んだのだが、toUpperCase()をしておかないとアウト(該当するスキーマがないので、org.dbunit.dataset.NoSuchTableExceptionになる。)。

SQL> select
 2 count(*)
 3 from all_objects
 4 where owner = 'HOGE';

 COUNT(*)
----------
     5

SQL> select
 2 count(*)
 3 from all_objects
 4 where owner = 'hoge';

 COUNT(*)
----------
     0


・・・しかし、なんで今まで動いていたんだ???