AnsweredAssumed Answered

Behavior of variables in embedded subprocesses

Question asked by meweiss on Dec 15, 2015
Latest reply on Dec 17, 2015 by meweiss
The documentation did not have any information on this, so I wanted to confirm what my experimental testing found:

1) If you have an embedded subprocesses, you don't need to re-define the variables in the start event of the subprocess. A sequence flow coming out of a gateway in an embedded subprocess can read the variable values defined in the parent.

2) If you have a naming conflict with a variable with the same ID but different default values in the parent start event and subprocess start event, activiti will use the value from the parent. I find this unintuitive, I would expect the embedded subprocess to pick up on the most "local" variable, aka the one in the subprocess start event.

See BPMN below which I tested with. In the gateway in the embedded subprocess, the variable evaluated to "true", which was the value set in the parent start event (false was the value set in the subprocess start event).

<?xml version="1.0" encoding="UTF-8"?>
<definitions expressionLanguage="http://www.w3.org/1999/XPath"
    id="definitions" targetNamespace="testSubProcessWithVarCategory"
    typeLanguage="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
    xmlns:activiti="http://activiti.org/bpmn"
    xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
    xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
    xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <process id="subprocessvarscope" isExecutable="true" name="test sub process">
        <startEvent activiti:async="true" id="start" name="Start">
            <extensionElements>
                <activiti:formProperty default="true" id="task1Var1Id"
                    name="var1_name" required="true" type="boolean"/>
                <activiti:formProperty id="task1Var2Id" name="var2_name"
                    required="true" type="string"/>
            </extensionElements>
        </startEvent>
        <serviceTask activiti:async="true"
            activiti:class="com.google.partnerservices.symphony.core.SymphonyTaskDelegate"
            id="task1" name="task 1">
            <extensionElements>
                <activiti:field name="variableNames">
                    <activiti:string><![CDATA[task1Var1Id, task1Var2Id]]></activiti:string>
                </activiti:field>
            </extensionElements>
        </serviceTask>
        <subProcess id="subProcess1" name="subProcess">
            <startEvent activiti:async="true" id="subProcessStart" name="sub Process Start Event">
                <extensionElements>
                    <activiti:formProperty default="false"
                        id="task1Var1Id" name="var1_name"
                        required="true" type="boolean"/>
                </extensionElements>
            </startEvent>
            <serviceTask activiti:async="true"
                activiti:class="com.google.partnerservices.symphony.core.SymphonyTaskDelegate"
                id="task2" name="if var1 = true"/>
            <endEvent activiti:async="true" id="subProcessEnd" name="sub process end event"/>
            <sequenceFlow id="subProcessFlow1"
                sourceRef="subProcessStart" targetRef="exclusivegateway1"/>
            <sequenceFlow id="subProcessFlow2" sourceRef="task2" targetRef="subProcessEnd"/>
            <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"/>
            <sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="task2">
                <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task1Var1Id == 'true'}]]></conditionExpression>
            </sequenceFlow>
            <serviceTask activiti:async="true"
                activiti:class="com.google.partnerservices.symphony.core.SymphonyTaskDelegate"
                id="servicetask1" name="Service Task"/>
            <sequenceFlow id="flow5" sourceRef="exclusivegateway1" targetRef="servicetask1">
                <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task1Var1Id == 'false'}]]></conditionExpression>
            </sequenceFlow>
            <sequenceFlow id="flow6" sourceRef="servicetask1" targetRef="subProcessEnd"/>
        </subProcess>
        <endEvent id="end" name="End"/>
        <sequenceFlow id="flow1" sourceRef="start" targetRef="task1"/>
        <sequenceFlow id="flow2" sourceRef="task1" targetRef="subProcess1"/>
        <sequenceFlow id="flow3" sourceRef="subProcess1" targetRef="end"/>
    </process>
</definitions>

Any reason why this behavior was chosen, since it feels more unintuitive? Can this be added to the Activiti documentation?

Outcomes