2013年10月25日金曜日

S2JDBC 列挙型を名前で使う

こんにちは。

S2JDBCでハマった事について(DBはPostgreSQL9.2)。
※ S2JDBCに特化した話題です。

■ 列挙型定義
以下の列挙型を定義します。

class enum TestEnum {
    A,B,C;
}

■ テーブル定義
データベースには以下のようなテーブルを定義します。

create table TEST (
  id serial,
  test varchar(1)
);

■ Entityクラスの作成
以下のEntityクラスを作成します。

class TestEntity {
    public id;

    @Enumerated(EnumType.STRING)
    public test;
}

■ DBにアクセスするクラスを作成

public class MainProgram {

    public void process() {
        SingletonS2ContainerFactory.init();
        JdbcManager jdbcManager = SingletonS2Container.getComponent("jdbcManager");
        List<TestEntity> result = jdbcManager.selectBySql(
                TestEntity.class,
                "select * from TEST",
                new Object[]{}
        ).getResultList();
        // omitted below - 以下、略 -
    }

    public static void main(String...args) {
        (new MainProgram()).process();
    }
}

--------
ポイントは、

  • エンティティのフィールドに列挙型を使用している
  • 列挙型を名前で扱う@アノテーションをつけている

という点です。

つまり、テーブル TEST のカラム test には、A, B, C という文字列が格納される想定です。
これを select すると、TestEntity.test を enum として取得できることを期待していました。

S2JDBCは基本的にJPA準拠なので、列挙型を名前で扱う場合、
このように「@Enumerated(EnumType.STRING)」と記載することになっているようです。

  • enum型を序数として扱いたい → EnumType.ORDINAL
  • enum型を名前として扱いたい → EnumType.STRING


ところが、このコードを実行すると、どうしても例外が発生してしまっていたのです。

例外の内容は以下。

Exception in thread "main" org.seasar.framework.exception.SQLRuntimeException: [ESSR0072]SQLで例外(SQL=[], Message=[型 int : hour で不正な値], ErrorCode=0, SQLState=22003)が発生しました

デバッグしてみると、どうやら@アノテーションで EnumType.STRING を指定してるにも関わらず、
EnumType.ORDINAL として処理していた(序数として扱っていた)が為に
[型 int : hour で不正な値]と出てしまっていたようです。


公式ドキュメントを探してみると以下のように記載されていました。

Seasar2.4.26 までは、@Enumerated アノテーションには対応していなく固定で名前が扱われるようになっていたようです。
現在の Seasar2.4.27 以降は、j2jdbc.dicon に以下の青字部分の記載を付け足す必要があったのです。

<component name="jdbcManager" class="org.seasar.extension.jdbc.manager.JdbcManagerImpl">
    <initMethod>
    @org.seasar.extension.jdbc.types.ValueTypes@setEnumDefaultValueType(
    @org.seasar.extension.jdbc.types.EnumType@class)
    </initMethod>
    ・・・略・・・
</component>


0 件のコメント:

コメントを投稿