jBPM5: プロセスに紐づいたエンティティを取得する

渡邊です。こんにちは。

jBPM5の勉強をしています。jBPM3.2からの変わりのように苦戦しています。
結論からいうと、これからお話する簡単なシナリオはjBPM5で実現できたのですが、あまりスマートではないので、もっとよい方法があると考えています。
ご存知の方がいらっしゃいましたら、フィードバックをいただけると幸いです。

稟議書を管理する業務システムに適用するとして、こんなシナリオを考えました。
Aさんが稟議書を申請し、Bさんがその稟議書を承認する


BPMN Diagramは次の通りです。問題を単純にする為に、「Aさんの稟議書作成タスク=プロセスの開始」としました。

システムの運用イメージは次の通りです。
1. Aさんは稟議書作成画面で稟議書を作成し、申請します。
2. Bさんはタスク一覧画面で自分が確認しなければならない稟議書を参照します。
ここでは2の実現方法について掘り下げたいので、3.以降の流れは省略します。

Bさんがタスク一覧画面にアクセスした際のロジックはどのようになるでしょうか。jBPM3.2では次の流れで実現していました。
1. Bさんにアサインされたタスクを取得する
2. タスクから稟議書の主キーを取り出す
3. 稟議書の主キーをもとにDBから稟議書を検索する
4. 検索結果を一覧画面に表示する

ここではBさんにアサインされたタスクから、稟議書の主キーを取り出す方法について更に掘り下げます。

まずはjBPM3.2による実現方法です。

Aさんの申請タスク
次のようなコードでプロセスを開始します。

    ProcessInstance proc = jbpmContext.newProcessInstance(PROCESS_NAME);
    proc.setKey(request.getId().toString());
    proc.signal("apply");

変数requestは、稟議書に対応するエンティティです。idは主キーです。ProcessInstance.setKey(String)を使って、ProcessInstanceに稟議書の主キーを紐づけました。

Bさんの承認タスク
「Bさんにアサインされたタスクを取得する」については割愛します。ここでは、既に変数taskInstanceにBさんにアサインされたタスク(TaskInstance)が代入されているとします。次のコードによって、タスクから(正確にはProcessInstanceを経由して)稟議書の主キーを取得できました。

    Long id = Long.parseLong(taskInstance.getProcessInstance().getKey());

あとはこの主キーをもとDBから稟議書を取得し、その情報を一覧に表示します。

前置きが長くなりましたが、ここからがjBPM5による実現方法です。

Aさんの申請タスク
プロセスの開始については、jBPM3.2とほとんどかわりません。

    Map params = new HashMap();
    params.put("requestId", request.getId().toString());
    ksession.startProcess(PROCESS_NAME, params);

Bさんの承認タスク
次のようなメソッドを実装しました。Bさんにアサインされたタスク(TaskSummary)を予め取得しておき、TaskServiceとともにこのメソッドに渡すと、稟議書のidを取得できます。

    public static Long findRequestId(TaskService taskClient, TaskSummary taskSummary) {
        Long id;

        Task task = taskClient.getTask(taskSummary.getId());
        TaskData taskData = task.getTaskData();
        Content content = taskClient.getContent(taskData.getDocumentContentId());
        ByteArrayInputStream bis = new ByteArrayInputStream(content.getContent());
        ObjectInputStream in;
        try {
            in = new ObjectInputStream(bis);
            Object result = in.readObject();
            in.close();
            String stringId = (String)((Map) result).get("requestId");
            id = (stringId == null ? null : Long.parseLong(stringId));
        } catch (Exception e) {
                throw new RuntimeException(e);
        }
        return id;
    }

BPMN Diagramの設定
実は、上記だけではfindRequestIdメソッドはnullを返すだけです。guvnorでBPMN Diagramのプロパティを次のように編集する必要があります。

BPMN Diagram全体のプロパティを開き、「プロパティ詳細 > Variable Definitions」を選択し、次の設定を追加します。

NameStandard TypeCustom Type
requestIdString

承認タスクのプロパティを開き、「プロパティ詳細 > DataInputSet」を選択し、次の設定を追加します。

NameStandard TypeCustom Type
requestId

同じく承認タスクのプロパティを開き、「プロパティ詳細 > Assignments」を選択し、次の設定を追加します。

From ObjectAssignment TypeTo ObjectTo Value
requestIdis equal to#{requestId}

本当にこんなことをやらないとだめなのか疑問ですが、以上の方法で実現できました。
そもそもjBPM3.2と同じ方式で実現しようというアプローチが間違っているかもしれません。

みな様のフィードバックをお待ちしております。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です