2008年10月10日金曜日

S2Dao ではまる

S2Daoで、Selectのパラメータに中途半端にMapが使えるため、はまってしまった。
問題となったDAOの定義は以下のようなもの(Interface, Foo はEntity)

Foo selectById(Object id);

使っている側はこれ、(key はHashMapで、"id":"1" のEntryあり)

Foo = fooDao.selectById((Map)key);

んで、出たエラーの概要がこれ、


org.seasar.framework.beans.IllegalPropertyRuntimeException:
[ESSR0059]クラス(org.seasar.springframework.batch.item.sample.Foo)のプロパティ(id)の設定に失敗しました。理由はjava.lang.IllegalArgumentException: object is not an instance of declaring class


うーーーむ、どうもObjectで指定するとEntityと同じTypeのオブジェクトが来たと思って処理するようで、Mapは考慮されていない。念のためにアノテーションを追加して以下のようにしてみると、

@Query("id = ?")
Foo selectById(Object q);

無理やりIDのカラムにあてはめようとしてエラーになっている模様。(@Arguments("id")も試したが結果は同じ)


org.seasar.framework.exception.SQLRuntimeException:
.....
Caused by: org.seasar.framework.exception.SSQLException:
[ESSR0072]SQLで例外(SQL=[SELECT T_FOOS.name, T_FOOS.value, T_FOOS.id FROM T_FOOS WHERE id = ?], Message=[17004], ErrorCode=null, SQLState={3})が発生しました
.....
Caused by: java.sql.SQLException: 列の型が無効です。


うーーーむ、どうやらMapからIDを拾ってはくれないようだ。S2Daoの仕様によると、argumentの型はPrimitiveかwrapperが基本で、DTOも使えるとのことで、Mapの記述はなし。S2JdbcがMapでQueryパラメータを指定できるので、同じようにできないかと思ったがやっぱり断絶があった模様。(もしかすると、最新のS2Daoならできるかも、、、、現在はS2Dao-1.0.47)

 続いて、最初からMapで指定したらどうなるか?

Foo selectById(Map q);

なんと!!! ちゃんととれてる。やればできるじゃないかS2DAOと思ったのも束の間、Mapとして与えるプロパティがどう変わっても取得できるものが同じでることが判明。つまり、

"id":"1" ==> Foo(id=1,...)
"id":"2" ==> Foo(id=1,...)

うーーん、これじゃ使えない、、、、試しに、@Arguments("id")としてみると。やっぱり「列の型が無効」とのこと。


Caused by: java.sql.SQLException: 列の型が無効です。


やっぱり、Mapはだめだ。

0 件のコメント: