Seam+jBPM=Bao

かくかくしかじかでSeamをいじる日々。Seamを使うことで、コーディング量とか新たに何か用意しなければいけない、ということはなくなる。

@Stateful
@Name("keihiApply")
public class KeihiApplyAction implements KeihiApply, Serializable
{
〜略〜
 @CreateProcess(definition="Keihi", processKey="#{keihiOrder.keihiOrderId}")
 public void submitOrder() {

  order = save(keihi); //中で、em使って経費情報永続!

  orderId      = order.getOrderId();
  amount       = order.getAmount();
 }
}

あの祭りの表現でいうと、@CreateProcessの宣言が「ベルトコンベアを用意する」ことで、processKey="#{keihiOrder.keihiOrderId}"が「そのコンベアに置く」といった感じ。便利でしょ。で、プロセスを進めたい場合は、

〜略〜
  @ResumeProcess(definition="keihi", processKey="#{keihiOrder.keihiOrderId}")
  public String approve() {
   processInstance.signal(); //先にすすめる
  }
〜略〜

って感じ。このメソッドは先にCreateProcessしたクラスと一緒じゃなくてもOK.
で、プロセス内で共有したい変数(上記でいう@CreateProcessのあるクラスと@ResumeProcessのあるクラスで共有したい、例えばorderId,amount)があれば、以下のように宣言するだけ。

  @Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
  long orderId;
  @Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
  BigDecimal amount = BigDecimal.ZERO;

これで、他のTaskやActionでも@Inでインジェクションできる。楽チン。ミソはprimitiveなもの、Stringなものを基本的にプロセス変数に使うこと。Serializableしてれば、実はどんなオブジェクトも格納可能だけど、クラスのバージョン非互換がでたらdeserializeできないから、やんないほうがいい。jBPMを使いたい人は(そういないと思うけど)Seamが一番簡単なのは間違いない。でも、やっと、ぶりの背中が見えてきた。DRY法則をちょこっと破ってるし、便利さも、まだ追いついてない。もうちょっとなんだけど。

Seamはタスク、アクティビティ、ユースケースに対して素直にクラスを用意して実装する。レイヤーというのをあまり意識しない(ような気がする)。もちろんサービスという単位で再利用したいことがでてくれば、それはそれでオブジェクトをリファクタリングすることになるのかな。むむむ、DDDの匂いが。。。。