Correlate a message to a sub process

Hello.

I modeled the following process:

TimerTest.bpmn (9.5 KB)

I want to to correlate ‘MSG_C’ in the sub process to spefic sub pocess instance identified by a variable.

If i remove ‘MSG_C’ from the sub process, i can see that the sub process has the variable ‘numberLocal’ set’ (which comes from the looped element variable ‘number’) by debugging the delegate of service task 'T3:

String number = (String) execution.getVariable("numberLocal");

→ gives me value ‘N1’.

I wonder if (including ‘MSG_C’ in the process model) i cant correlate the message to one of the sub processes by:

processEngine.getRuntimeService().createMessageCorrelation("MSG_C").processInstanceVariableEquals("numberLocal", "N1").correlate();

Error:

Cannot correlate a message with name 'MSG_C' to a single execution. {number of elements in ${numbers} collection} executions match the correlation keys

Of source, ‘N1’ is an element of the ${numbers} collection, which is the collection of the looped sub process.

I know that each sub process has its variable ‘numberLocal’ (see above).

Can you tell me what i am doing wrong?

Test case:

@Test
    public void testTimer()
    {
        String bkMain = "bkMain1";
        
        List<String> numbers = new ArrayList<>();
        
        numbers.add("N1");
        numbers.add("N2");
        numbers.add("N3");
        
        RuntimeService runtimeService = processEngine.getRuntimeService();
        
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("TimerTestProcess", bkMain,
                MapBuilder.getInstance().addEntry("numbers", numbers).create());
        runtimeService.correlateMessage("MSG_B", bkMain);
        
        assertThat(instance).hasPassed("EV_MSG_B");
        
        List<Task> taskT2List = processEngine.getTaskService().createTaskQuery().taskDefinitionKey("TASK_T2").list();
        assertEquals(3, taskT2List.size());
        
        // finsh all 'T2' tasks
        for (Task t : taskT2List) 
        {
            processEngine.getTaskService().complete(t.getId());
        }               
        
        // works
        // processEngine.getRuntimeService().createMessageCorrelation("MSG_C").correlateAll();
        
        // what to for e.g. sub process with variable (${numberLocal == "N1"})? --> does NOT work
        processEngine.getRuntimeService().createMessageCorrelation("MSG_C").localVariableEquals("numberLocal", "N1").correlate();
        
        assertThat(instance).isEnded();
    }

It works if i use a call activity. Im fine with that, thank you.

You can always use expressions to append some value from variables to your message, like this:
image

This way you can correlate to your very specific subprocess by making the same string in your correlation message.

Another thing i like to do is to mark my message receiver events as “Async After” always. This way i dont lose any messages if the next delegates throws some error.

By the way, be aware that if you use that “VariableEquals” query anywhere in your project, your database can get some heavy queries, because the variable table is one of the biggest ones, and by default there are no index that uses variable name and value.

If you really need to use this, you should put an index, but in most scenarios you have another way to do the same thing. Maybe you should really use multi instance call activity and set a nice businesskey for each of the child process, so you can use the businesskey in your query. That should be much faster!