cancel
Showing results for 
Search instead for 
Did you mean: 

No activity id on execution with boundary event

schalmers
Champ in-the-making
Champ in-the-making
Hi,

We have a process with a receive task. When we want to signal this we query for the execution using the process key, activity ID and a variable value which helps to uniquely identify the process.

Our problem is that when we added a boundary timer event to the receive task the query no longer works since the activity id is no longer set on the process.

We had expected that adding a boundary event would not require any changes to the query.

Please could you confirm if this is correct behaviour or a bug?

Thanks.
13 REPLIES 13

frederikherema1
Star Contributor
Star Contributor
The execution-id of an activity with a boundry-event is indeed different from the execution-id of the general process, this is not a bug, just how activiti handles boundry-events internally.

However, the task should still be query'able using the processInstanceId (not as executionId).

schalmers
Champ in-the-making
Champ in-the-making
Thanks for your reply.

Yes, we found that we had to query for the process instance matching on the process key and variable,and then a further execution query using the activity id and process instance id from the result of the first query. This gives us the correct execution to signal.

This may be an internal implementation detail, but we found it quite confusing that the query behaviour for an activity changes when a boundary event is added. So it seems that the implementation detail has leaked into the API to some extent.

Thanks & Regards
Stuart

edi1
Champ in-the-making
Champ in-the-making
hi,

I have a similar issue when having two parallel paths of execution running the same subprocess, containing a receive task with a timer boundary event:

[img]http://imageshack.us/a/img839/3922/processk.png[/img]

Sourcecode is available at git://github.com/esz/activiti.git

My intention is to selectively signal the receive tasks by first printing the current execution id (or sending it to an external service) - and then get a callback with this id and signal
the correct path of the 2 parallel ones.

To get the correct execution id after having received the callback, my code is as follows:


  ActivityExecution exec = (ActivityExecution) runtimeService
     .createExecutionQuery().executionId(id).singleResult();
  // there's only one child execution (=receive task with timer) possible according to the process model
  ActivityExecution child = exec.getExecutions().get(0);
  runtimeService.signal(child.getId());

However this results in a NPE, because Context.getCommandContext() resolves to null in org.activiti.engine.impl.persistence.entity.ExecutionEntity.ensureExecutionsInitialized()

Is this a possible bug? Or does anyone have an idea how this can be solved in a better way? Querying by process instance id and activity id, as proposed earlier, doesn't work out here.

regards, edi

meyerd
Champ on-the-rise
Champ on-the-rise
Thanks for your reply.

Yes, we found that we had to query for the process instance matching on the process key and variable,and then a further execution query using the activity id and process instance id from the result of the first query. This gives us the correct execution to signal.

This may be an internal implementation detail, but we found it quite confusing that the query behaviour for an activity changes when a boundary event is added. So it seems that the implementation detail has leaked into the API to some extent.

Thanks & Regards
Stuart

Hi Stuart,

See ACT-1374, we added the possibility to query for an excution with processVariableEquals(). This enables you to solve this problem in a single Query.

edi1
Champ in-the-making
Champ in-the-making
hi,

I have a similar issue when having two parallel paths of execution running the same subprocess, containing a receive task with a timer boundary event:

[img]http://imageshack.us/a/img839/3922/processk.png[/img]

Sourcecode is available at git://github.com/esz/activiti.git

My intention is to selectively signal the receive tasks by first printing the current execution id (or sending it to an external service) - and then get a callback with this id and signal
the correct path of the 2 parallel ones.

To get the correct execution id after having received the callback, my code is as follows:


  ActivityExecution exec = (ActivityExecution) runtimeService
     .createExecutionQuery().executionId(id).singleResult();
  // there's only one child execution (=receive task with timer) possible according to the process model
  ActivityExecution child = exec.getExecutions().get(0);
  runtimeService.signal(child.getId());

However this results in a NPE, because Context.getCommandContext() resolves to null in org.activiti.engine.impl.persistence.entity.ExecutionEntity.ensureExecutionsInitialized()

Is this a possible bug? Or does anyone have an idea how this can be solved in a better way? Querying by process instance id and activity id, as proposed earlier, doesn't work out here.

regards, edi

Any ideas on this? I print the process instance id and the execution id for both parallel paths and then read from stdin which of the paths to stop. I expect one of the 2 execution ids  printed previously as user input and then look up the child execution of that execution hower I get a NPE with the following stacktrace.


java.lang.NullPointerException
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.ensureExecutionsInitialized(ExecutionEntity.java:584)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.getExecutions(ExecutionEntity.java:577)
at com.myprocess.TestProcess.testProcess(TestProcess.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Am I doing something wrong here?

regards, eduard

jbarrez
Star Contributor
Star Contributor
If I understand it correctly, it is a bug. You should get two execution ids for that process.
Can you paste the records of the ACT_RU_EXECTION table for that specific process?

edi1
Champ in-the-making
Champ in-the-making
contents of act_ru_execution while process is waiting in both receive tasks:


ID_ REV_ PROC_INST_ID_ BUSINESS_KEY_ PARENT_ID_ PROC_DEF_ID_ SUPER_EXEC_ ACT_ID_ IS_ACTIVE_ IS_CONCURRENT_ IS_SCOPE_ IS_EVENT_SCOPE_ SUSPENSION_STATE_ CACHED_ENT_STATE_
5 1 5 null null p:1:4 null parallelgateway1 FALSE FALSE TRUE FALSE 1 0
9 1 5 null 5 p:1:4 null null FALSE TRUE FALSE FALSE 1 7
10 1 5 null 5 p:1:4 null null FALSE TRUE FALSE FALSE 1 7
11 1 5 null 9 p:1:4 null null FALSE FALSE TRUE FALSE 1 0
14 1 5 null 11 p:1:4 null receivetask1 TRUE FALSE TRUE FALSE 1 4
18 1 5 null 10 p:1:4 null null FALSE FALSE TRUE FALSE 1 0
21 1 5 null 18 p:1:4 null receivetask1 TRUE FALSE TRUE FALSE 1 4

edi1
Champ in-the-making
Champ in-the-making
The problem is when I lookup execution 11..


ActivityExecution exec = (ActivityExecution) runtimeService
     .createExecutionQuery().executionId(11).singleResult();

and try to get the child executions (expecting that there's exactly one child execution with id = 14, see table)..


ActivityExecution child = exec.getExecutions().get(0);

.. a NPE is thrown in that line (in org.activiti.engine.impl.persistence.entity.ExecutionEntity#ensureExecutionsInitialized())

jbarrez
Star Contributor
Star Contributor
hmmm, then I'm at my wits end. Can you wrap up the process you have and create a unit test for it (see http://forums.activiti.org/en/viewtopic.php?f=6&t=4645).
You can attach the jira straight to my name.