[Seasar-user:17849] [SAStruts]インターセプター(Interceptor)中でのDBアクセスの実装方法について
[E-MAIL ADDRESS DELETED]
[E-MAIL ADDRESS DELETED]
2009年 6月 25日 (木) 06:51:13 JST
田中と申します。
お世話になっております。
SAStrutsにてシステムメンテナンス中等のチェックを行うため、
インターセプター(Interceptor)中でのDBアクセスを検討しております。
動作確認中に不可解なエラーが出てきましたので、
使い方の問題など無いかご確認させてください。
試しに、先日ご確認させて頂いた認証Interceptor
<component name="loginCheckInterceptor" instance="request"
class="sample.sastruts.aop.interceptor.LoginCheckInterceptor"/>
に、S2JDBCチュートリアルを参考にDBアクセス処理を追加しました。
public Object invoke(MethodInvocation invocation) throws Throwable {
(中略)
JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);
Long count = jdbcManager.from(Employee.class).getCount();
System.out.println( count );
すると、上記の処理は成功するのですが、後続のサービスのDBアクセスで
以下のエラーが発生してしまいました。
※Tomcat起動後の初回アクセスではエラーですが、2回目以降は成功する状態です。
javax.servlet.ServletException: org.seasar.framework.exception.SIllegalArgumentException: [E
SSR0094]IllegalArgumentExceptionがクラス(sample.sastruts.aop.entity.Employee)[WebappClassLoa
der
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
[E-MAIL ADDRESS DELETED]
]の型(java.lang.Integer)[null]のフィールド(id)に型(java.lang.Integer)[null]の値(1,010)を設定
するときに発生しました。対象のクラスは(sample.sastruts.aop.entity.Employee)[org.seasar.frame
[E-MAIL ADDRESS DELETED]]です。
org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:535)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:433)
org.seasar.struts.action.S2RequestProcessor.process(S2RequestProcessor.java:125)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.seasar.extension.filter.RequestDumpFilter.doFilter(RequestDumpFilter.java:127)
org.seasar.framework.container.hotdeploy.HotdeployFilter.doFilter(HotdeployFilter.java:75)
org.seasar.framework.container.filter.S2ContainerFilter.doFilter(S2ContainerFilter.java:79)
org.seasar.struts.filter.RoutingFilter.forward(RoutingFilter.java:219)
org.seasar.struts.filter.RoutingFilter.doFilter(RoutingFilter.java:90)
org.seasar.framework.container.hotdeploy.HotdeployFilter.doFilter(HotdeployFilter.java:63)
org.seasar.framework.container.filter.S2ContainerFilter.doFilter(S2ContainerFilter.java:79)
org.seasar.extension.filter.EncodingFilter.doFilter(EncodingFilter.java:69)
切り分けとして、以下も試してみました。
・トランザクション制御を追加し、インターセプター内でコミットすると、
後続のサービスで「既にトランザクションは終了しています。」と怒られる
・トランザクションを分離しようと、サービスに切り出して、メソッドに
「@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)」
を付けたところ、最初の事象に戻ってしまいました
※トランザクション制御の問題ではないようですが、
インターセプター中の操作が後続サービスにも影響しているようです。
タイミングの問題も含まれているので、使い方がまずい感じがしています。
(インターセプター中のjdbcManagerの使い方など。)
できれば、インターセプター中のDB操作が後続のサービスに影響しないような
実装(別コネクションの利用)が望ましいと思いますが、そのような実装は可能でしょうか。
有識者の方にコメントを頂ければ幸いです。
Seasar-user メーリングリストの案内