Seasar2のサポートはずいぶんと前に終了しましたが、SAStrutsのライブラリを使う機会があり、そこで表題のエラーに遭遇したので記事を書くことにしました。
アクセス解析を見てると、古い技術の記事もたまにアクセスがあったりするので、もしかしたら1,2人くらいには役に立つ情報かもしれません。
UnsupportedOperationException
この例外自体はJavaの標準的なExceptionの1つであり、「サポートされていない操作が行われた」という例外です。
多くの場合、意図的にThrowされるExceptionでしょう。非推奨だったAPIがバージョンアップでついに廃止APIになったときとか。
今回発生したエラーは以下でした。
java.lang.UnsupportedOperationException: [ESSR0746]エンティティ(XXXX)の検索にFOR UPDATEが指定されましたが、DBMS(hsql)ではサポートされていません。 at org.seasar.extension.jdbc.query.AutoSelectImpl.forUpdate(AutoSelectImpl.java:1370)
AutoSelectImplはS2JDBCの機能の1つにある「SQLを自動生成するクラス」です。
そこでこのエラーが発生するということは、なんとなく設定の問題なのかなと思いました。
ライブラリである以上、ソースのバグであるなら既に誰かが報告しているでしょう。
今回の根本的な原因は「s2jdbc.dicon」のダイアレクトに関する設定の漏れでした。
使用しているDBに応じて、dialectプロパティを書いてあげる必要がありました。
追記したことで、エラーが発生した処理も正常に動作するようになりました。
UnsupportedOperationException自体は数多くのライブラリで発生する可能性があるでしょう。
発生した場合は、その次に書かれているであろうThrowしたクラスを見て、そいつがどんなものか調査してみましょう。
ちなみに、念のため該当箇所のソースを見てみたら、まさにという記述でした。
public AutoSelectforUpdate() { final DbmsDialect dialect = getJdbcManager().getDialect(); if (!dialect.supportsForUpdate(SelectForUpdateType.NORMAL, false)) { final EntityMeta entityMeta = getJdbcManager() .getEntityMetaFactory().getEntityMeta(baseClass); throw new UnsupportedOperationException(MessageFormatter .getMessage("ESSR0746", new Object[] { entityMeta.getName(), dialect.getName() })); } forUpdateType = SelectForUpdateType.NORMAL; return this; }
JDBCManagerからdialectを取得して、DBがfor update文をサポートしているかを判定しています。
ここら辺から、JDBC関連の特にdialectに関する問題であることが推測できます。