日本語テーブルを使うとOracleで一意キーの情報がとれない件

追記

  • 影響を受けるのは2箇所ではなく3箇所でした。


10gや11gで発生することがわかっています。

どいうことかというと、

java.sql.DatabaseMetaData metaData = ...
metaData.getIndexInfo(null, "schema", "あいうえお", true, false); // 3番目のパラメータがテーブル名

とすると、ORA-17068の例外が発生します。


S2JDBC-Genでは、エンティティのJavaコード生成で、このメソッドを呼んでいるのですが、次のバージョンから0.9.4からこれに対応し、日本語テーブルの場合は、一意キーの情報を取得しないようにします。

一意キーの情報を取得できないことで、2箇所3箇所で影響を受けます。

  • @Columnのunique要素を正しく出力できない
  • @OneToOneを出力できない(代わりに@ManyToOneになる)
  • @TableのuniqueConstraints要素に複合一意キーを出力しない

自動で判別できないので、これらの情報は、コード生成後に直接修正してもらう必要があります。


S2JDBC-Gen 0.9.3を使っていてこの問題に対処するには、クラスを1つ作成し、そのクラスをタスクの属性に加えます。
作成するクラスは、org.seasar.extension.jdbc.gen.internal.factory.FactoryImplのサブクラスです。

public class MyFactory extends FactoryImpl {

    @Override
    public DbTableMetaReader createDbTableMetaReader(Command command,
            DataSource dataSource, GenDialect dialect, String schemaName,
            String tableNamePattern, String ignoreTableNamePattern) {

        return new DbTableMetaReaderImpl(dataSource, dialect, schemaName,
                tableNamePattern, ignoreTableNamePattern) {

            @Override
            protected void doDbUniqueKeyMeta(DatabaseMetaData metaData,
                    DbTableMeta tableMeta, Set<String> primaryKeySet) {
                // do nothing.
            }
        };
    }
}

createDbTableMetaReaderメソッドをオーバーライドし、DbTableMetaReaderImpl型の無名クラスを返します。無名クラスではdoDbUniqueKeyMetaメソッドをオーバライドして何の処理も行わないようにしてください。こうすることで、一意キーの情報を取得しなくなります。

Gen-EntityタスクのfactoryClassName属性に作成したクラスの名前を指定し実行してください。

<gen-entity
    rootPackageName="examples"
    factoryClassName="examples.MyFactory"
    classpathRef="classpath"
/>

この問題はS2JDBC自体の実行には何の影響もあたえません。
S2JDBC-Genでコード生成するときだけの問題です。