[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 メーリングリストの案内