ExecutionQuery().processInstanceId(id).activityId(activityId).list() not working as expected


#1

In a Unit test I try to detected if the serviceTask “submitInvoiceTask” has completed. The BPMN snippet is as follows:

<process id="SubmitInvoiceProcess" name="Submit Invoice Process" isExecutable="true">

	<startEvent id="start" name="Start" />

	<sequenceFlow id="start-submitInvoiceTask" sourceRef="start" targetRef="submitInvoiceTask" />

	<serviceTask id="submitInvoiceTask" flowable:async="true" flowable:expression="#{invoiceService.submit(invoice)}">
		<extensionElements>
			<flowable:failedJobRetryTimeCycle>R3/PT1S</flowable:failedJobRetryTimeCycle>
		</extensionElements>
	</serviceTask>

When the submitInvoiceTask has been reached, the following print statment gives me the excepcted output:

for (Execution e : runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).list()) {
  System.out.println(e.getActivityId());
}

prints:
Executions:
null
submitInvoiceTask

However if I add the activityId to the query, the serviceTask is no more listed:

for (Execution e : runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).activityId("submitInvoiceTask").list()) {
  System.out.println(e.getActivityId());
}

prints:
Executions:

I tried several more alternatives but I found no solution how to precisely query if the serviceTask is active. Did I use the API not correctly or is this probably a bug?

Cheers
Martin


#2

Hi Martin,

When adding the activityId query option this is done in the SQL query:

<if test="activityId != null">
    and RES.ACT_ID_ = #{activityId} and RES.IS_ACTIVE_ = #{isActive}
</if>

The IS_ACTIVE part probably causes the issue that it’s not returned. The reason why it’s not set to active is that it will be handled asynchronously by the async executor. As an alternative you could query on open executable or timer jobs for the process instance to see if the job was executed.

Best regards,

Tijs


#3

Okay, I see the point. As a temprary solution I resorted to:

runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).list().stream()
				.filter(e -> "submitInvoiceTask".equals(e.getActivityId())).findFirst().isPresent()

Even though I think the API has a pitfall here by automatically adding a second parameter (isActive) to the first one (activityId). I propose therefore to change it and add “active” as additional method in the fluent API:

runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).activityId("submitInvoiceTask").active(true).list();

I could contribute this, If you agree. What do you think?

Cheers
Martin


#4

Hi Martin,

I looked a bit more into the cases where the execution is set to active = false. And with async service tasks this only happens when the job is retried. Is that happening in your use case? If this is not the case, could you check when the IS_ACTIVE_ column value gets set to false? Or can you create a unit test reproducing the issue?

Best regards,

Tijs


#5

Hi Tijs,

Yes, it is a retry use case which I simulate in a unit test. I evaluate this functionality and probably will use it for an insurance company’s project. The source is available on https://github.com/martin-schaefer/flowable-examples, the relevant location is in waitForSubmitInvoiceTaskCompletion(…)

Cheers,
Martin


#6

why this error comming

image