JBoss jBPM と Seasar の連携方法

次の仕事で使うかもしれないとのことで、ワークフローエンジンについていろいろ調べています。
まずは JBoss jBPM を、Seasar ベースのアプリケーションで使う場合必要な、トランザクション制御の連携方法について。

jBPM 独自で Session を管理する場合

S2Hibernate-JPA の設定を参考に、hibernate.cfg.xml に以下の設定を記述する。

<hibernate-configuration>
  <session-factory>

    <!-- jdbc.dicon に登録した DataSource を利用する -->
    <property name="connection.datasource">jdbc/dataSource</property>

    <!-- JNDI の解決に S2 のコンポーネント名を使用する -->
    <property name="jndi.class">
      org.seasar.extension.j2ee.JndiContextFactory
    </property>

    <!-- S2 のトランザクション制御と連携する -->
    <property name="transaction.factory_class">
      org.hibernate.transaction.JTATransactionFactory
    </property>
    <property name="transaction.manager_lookup_class">
      org.seasar.hibernate.jpa.transaction.SingletonTransactionManagerProxyLookup
    </property>

    <!-- その他の設定 -->

  </session-factory>
</hibernate-configuration>

jBPMHibernate を使ってデータを永続化してますが、アプリケーションで Hibernate を使わない or Hibernate を使っても同じデータにアクセスしない場合はこの方法が使えると思います。
S2-Tiger に入ってる jdbc.dicon の DataSource は、なぜか jdbc/DataSource と大文字になってるので、注意が必要です。S2Unit や他のプロダクトでは小文字の jdbc/dataSource をデフォルトにしているので、小文字で統一するのが良いでしょう。

あと、実際には Hibernate が良しなに処理してくれるようですが、一応、jBPMトランザクション制御を無効にしておいたほうが良いかもしれません。jbpm.cfg.xml に以下の設定を追加します。

<jbpm-configuration>

  <jbpm-context>
    <!-- jBPM のトランザクション制御を無効にする -->
    <service name="persistence">
      <factory>
        <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
          <field name="isTransactionEnabled"><false/></field>
        </bean>
      </factory>
    </service>
    <service name="tx"
        factory="org.jbpm.tx.TxServiceFactory" />
    <service name="message"
        factory="org.jbpm.msg.db.DbMessageServiceFactory" />
    <service name="scheduler"
        factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
    <service name="logging"
        factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
    <service name="authentication"
        factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
  </jbpm-context>

  <!-- その他の設定 -->

</jbpm-configuration>

jBPM とアプリケーションで Session を共有する場合

いろいろ調べてみたんですが、結局 JbpmConfiguration から JbpmContext を取得したときに、setSession() するのが簡単そうです。

S2Hibernate3 だったら、

S2SessionFactoryImpl sessionFactory;

JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
jbpmContext.setSession(sessionFactory.getSession());

S2Hibernate-JPA だったら、

EntityManager entityManager;

JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
jbpmContext.setSession((Session) entityManager.getDelegate());

こんな感じになります。