S2Hibernate で read only な Session
ちょっとした思いつき.
S2Hibernate を使うと,トランザクションのコミット前に Session#flush()
を呼び出してくれます.
でも,大量の永続オブジェクトを読み込んだ場合など,Session#flush()
は結構重い処理になりかねません.
そんなわけで (どんなわけで?),read only なセッションでは Session#flush()
を呼び出さないようにできるといいかも.
ということでまずは S2Session
にプロパティを追加!!
public boolean isReadOnly(); public void setReadOnly(boolean readOnly);
そして S2SessionImpl
でこいつを実装!!
private boolean readOnly_; public boolean isReadOnly() { return readOnly_; } public void setReadOnly(boolean readOnly) { this.readOnly_ = readOnly; }
S2SessionFactory#closeSession()
でこいつをチェック!!
if (session != null && session.isOpen()) { try { if (!session.isReadOnly()) { session.flush(); } } finally { Connection con = session.close(); ConnectionUtil.close(con); } }
そして read only なセッションのためのインターセプタを作成!!
package org.seasar.hibernate.interceptor; import net.sf.hibernate.FlushMode; import org.aopalliance.intercept.MethodInvocation; import org.seasar.framework.aop.interceptors.AbstractInterceptor; import org.seasar.hibernate.S2Session; import org.seasar.hibernate.S2SessionFactory; public class ReadOnlySessionInterceptor extends AbstractInterceptor { private S2SessionFactory sessionFactory; public void setSessionFactory(S2SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Object invoke(MethodInvocation invocation) throws Throwable { S2Session session = sessionFactory.getSession(); session.setReadOnly(true); session.setFlushMode(FlushMode.NEVER); return invocation.proceed(); } }
こいつを s2Hibernate.dicon
に追加!!
<component name="readOnly" class="org.seasar.hibernate.interceptor.ReadOnlySessionInterceptor"/>
これでこんな風に使えます.
<component name="..." class="..."> <aspect>j2ee.requiredTx</aspect> <aspect pointcut="find.*">s2hibernate.readOnly</aspect> </component>
この場合は find
で始まるメソッドだけが read only なセッションになります.
どうでしょう?>id:kenichi_okazaki さん
ちなみに Spring ではトランザクションのモードが read only だと Session#flush()
しないことになっているようです.でもそれ,ちょっとイマイチな気のせいが.
例えば Hibernate で参照だけした結果を JDBC 直で更新する場合には無効だよねぇとか.
例えば RDB (Hibernate) は参照するだけなんだけど JMS を更新する場合には無効だよねぇとか.
なぜ JTA ではトランザクションに read only とかってモードがないかといえば,それはトランザクションよりもむしろリソースに設定するものだからだと思うのですよね.
まぁ,JTA 使うと JMS うまくいかない Spring ではあまり気にしなくていいのかもしれませんが.