conditionExpression not working on sequenceFlow

Hi,

I am new to flowable.

I have created a simple bpmn file that executes a set of java delegate services tasks, one of the sequenceFlows contains a conditionExpression below:

        <sequenceFlow id="PersistenceFlow" sourceRef="registerCompoundStartEvent" targetRef="PersistenceDelegateServiceTask">
			<conditionExpression xsi:type="tFormalExpression">
				${entityDefinition.validated}
			</conditionExpression
		</sequenceFlow>

The entityDefinition object is dropped into the workflow at the start:

    Map<String, Object> variables = new HashMap<>();
    variables.put(WorkflowService.ENTITY_DEFINITION, entityTree);
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    repositoryService.createDeployment()
            .addInputStream("workflowcompound.bpmn20.xml", new ByteArrayInputStream(compoundWorkflowBPMN.getBytes()))
            .deploy();
    RuntimeService runtimeService = processEngine.getRuntimeService();

The sequence flow task (ValidationDelegateService) before the PersistenceDelegateServiceTask sets the
entityDefinition.validated = true; like below:

    EntityTree entityTree = (EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION);
    entityTree.setValidated(true);

but the Sequenceflow PersistenceFlow does not see the update set to true and will not run, but in debugging I can see that it has been set = true inside the java delegate class that set it?

It is a simple conditional flow that does not require at this stage an exclusive gateway, any ideas?

Thanks,
Iain

Forgive me if I’m incorrect but I think what you’re looking for is execution.setVariable()
Something like this in your ValidationDelegateService may set it so that the change will be seen by the engine when control is handed back from the delegate:

execution.setVariable(WorkflowService.ENTITY_DEFINITION, (EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION).setValidated(true));

@jonathanlevis beat me to it.

Are you saving it back with a setVariable? Flowable serializes Java objects to store them as variables in the database, so the object that the sequence flow is evaluating may not be the same object you are setting the value on.

Yes I am, see below:
,
public class ValidationDelegateService implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
EntityTree entityTree = (EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION);
entityTree.setValidated(true);
}
}

As I am getting the handle to the EntityTree object using execution.getVariable() and setting the validated member variable via the setter that should update the EntityTree in the dB? However the next task in the
sequence flow below:

  <sequenceFlow id="PersistenceFlow" sourceRef="registerCompoundStartEvent" targetRef="PersistenceDelegateServiceTask">
			<conditionExpression xsi:type="tFormalExpression">
				${entityDefinition.validated}
			</conditionExpression
		</sequenceFlow>

is always getting false in the condition above…?

If I negate the expression as shown below:

${!entityDefinition.validated}

it will call the PersistenceDelegateServiceTask task (because at the workflow level it is still evaluating = false even though it was set = true) and via the debugger I can see that the validate variable has in fact been set = true inside the PersistenceDelegateServiceTask but the workflow is not seeing it.

Setting it this way didn’t do anything either:

((EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION)).setValidated(true);

The service method that sets up and runs the workflow is below:

@Override
public void create(EntityTree entityTree) throws SystemException, UserException {
Map<String, Object> variables = new HashMap<>();

    variables.put(WorkflowService.ENTITY_DEFINITION, entityTree);

    // Retrieve the workflow from the dB (for now it is hardcoded above until the table is ready)
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    repositoryService.createDeployment()
            .addInputStream("workflowcompound.bpmn20.xml", new ByteArrayInputStream(compoundWorkflowBPMN.getBytes()))
            .deploy();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance pi;

    try {
        pi = runtimeService.startProcessInstanceByKey("REGISTER_COMPOUND", variables);
    } catch (BpmnError e) {     // Todo - check if we need to use Boundary Error Event
        String str = e.getMessage();
        throw new SystemException(e.getErrorCode());
    } catch (FlowableException re) {
        String str = re.getMessage();
    }
}

I’m confused :frowning:

When you call getVariable, it deserializes a copy of the object from the database. Simply setting the variable on the returned object is not sufficient to to persist it back to the database. You need an explicit execution.setVariable call.

@Override
public void execute(DelegateExecution execution) {
  EntityTree entityTree = (EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION);
  entityTree.setValidated(true);
  execution.setVariable(WorkflowService.ENTITY_DEFINITION, entityTree);
}

I tried that and it didn’t work. It is a spring boot application using the h2 dB for development.
below is my bpmn:

        <definitions id="definitions" 
        xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            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:flowable="http://flowable.org/bpmn" 
            typeLanguage="http://www.w3.org/2001/XMLSchema" 
            expressionLanguage="http://www.w3.org/1999/XPath" 
            targetNamespace="http://www.flowable.org/processdef>" 
            <process id="REGISTER_COMPOUND" name="Register Compound" isExecutable="true"> 
                <startEvent id="registerCompoundStartEvent" name="Start"/> 
                <serviceTask id="ValidationDelegateServiceTask" name="Validation" flowable:class="com.dotmatics.register.workflow.flowable.delegate.ValidationDelegateService"/> 
                <serviceTask id="PersistenceDelegateServiceTask" name="Persistence" flowable:class="com.dotmatics.register.workflow.flowable.delegate.PersistenceDelegateService"/> 
                <sequenceFlow id="ValidationFlow" sourceRef="registerCompoundStartEvent" targetRef="ValidationDelegateServiceTask"> 
                </sequenceFlow> 
                <sequenceFlow id="PersistenceFlow" sourceRef="registerCompoundStartEvent" targetRef="PersistenceDelegateServiceTask"> 
                      <conditionExpression xsi:type="tFormalExpression"> 
                           ${entityDefinition.validated} 
                      </conditionExpression> 
                </sequenceFlow> 
                <endEvent id="registerCompoundEndEvent" name="End"></endEvent> 
            </process> 
        </definitions>

the method that runs the workflow

@Override
public void create(EntityTree entityTree) throws SystemException, UserException {
    Map<String, Object> variables = new HashMap<>();

    variables.put(WorkflowService.ENTITY_DEFINITION, entityTree);

    // Retrieve the workflow from the dB (for now it is hardcoded above until the table is ready)
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    repositoryService.createDeployment()
            .addInputStream("workflowcompound.bpmn20.xml", new ByteArrayInputStream(compoundWorkflowBPMN.getBytes()))
            .deploy();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance pi;

    try {
        pi = runtimeService.startProcessInstanceByKey("REGISTER_COMPOUND", variables);
    } catch (BpmnError e) {     // Todo - check if we need to use Boundary Error Event
        String str = e.getMessage();
        throw new SystemException(e.getErrorCode());
    } catch (FlowableException re) {
        String str = re.getMessage();
    }
}

the ValidationDelegateService delegate

public class ValidationDelegateService implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
EntityTree entityTree = (EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION);
entityTree.setValidated(true);
execution.setVariable(WorkflowService.ENTITY_DEFINITION, entityTree);
/*
EntityTree compoundTree = entityTree.path(“COMPOUND_SAMPLE”, CompoundBatch.COMPOUND_BATCH_TYPE, Compound.COMPOUND_TYPE);
Compound compound = new Compound(compoundTree);
*/
}
}

the PersistenceDelegateService that should be called when validate == true

public class PersistenceDelegateService implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
// Todo - persistence the data.
EntityTree entityTree = (EntityTree) execution.getVariable(WorkflowService.ENTITY_DEFINITION);

    System.out.println("Entity has been persisted");
}

}

The following works correctly, what does your EntityTree class look like? If it’s in your posts I’m having trouble finding it (three back ticks (`) before and after code will format it).

pop.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <flowable.version>6.4.2</flowable.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-spring-boot-starter</artifactId>
            <version>${flowable.version}</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

DemoApplication.java

package com.example.demo;

import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    JavaDelegate setVariable () {
        return execution -> {
            SomeObject object = execution.getVariable("object", SomeObject.class);
            object.setValidated(true);
            execution.setVariable("object", object);
        };
    }

    @Bean
    JavaDelegate variableSet(){
        return execution -> {
            SomeObject object = execution.getVariable("object", SomeObject.class);
            System.out.println("Validate = " + object.isValidated());
        };
    }

    @Bean
    CommandLineRunner runner (RuntimeService runtimeService) {
        return args -> {
            SomeObject object = new SomeObject();
            object.setValidated(false);

            runtimeService.createProcessInstanceBuilder().processDefinitionKey("serialCondition").variable("object", object).start();
        };
    }
}

class SomeObject implements Serializable {
    private boolean validated = false;

    public boolean isValidated() {
        return validated;
    }

    public void setValidated(boolean validated) {
        this.validated = validated;
    }
}

resources/processes/Serial_Condition.bpmn20.xml

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.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:design="http://flowable.org/design" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://flowable.org/test" design:palette="flowable-process-palette">
  <process id="serialCondition" name="Serial Condition" isExecutable="true" flowable:candidateStarterGroups="flowableUser">
    <extensionElements>
      <design:stencilid><![CDATA[BPMNDiagram]]></design:stencilid>
      <design:language><![CDATA[English]]></design:language>
      <design:creationdate><![CDATA[2020-01-14T13:57:59.442Z]]></design:creationdate>
      <design:modificationdate><![CDATA[2020-01-14T14:02:34.971Z]]></design:modificationdate>
    </extensionElements>
    <startEvent id="startnoneevent1" flowable:initiator="initiator" flowable:formFieldValidation="false">
      <extensionElements>
        <flowable:work-form-field-validation><![CDATA[false]]></flowable:work-form-field-validation>
        <design:stencilid><![CDATA[StartNoneEvent]]></design:stencilid>
      </extensionElements>
    </startEvent>
    <endEvent id="endNoneEvent1">
      <extensionElements>
        <design:stencilid><![CDATA[EndNoneEvent]]></design:stencilid>
      </extensionElements>
    </endEvent>
    <sequenceFlow id="sequenceFlow1" sourceRef="startnoneevent1" targetRef="serviceTask1">
      <extensionElements>
        <design:stencilid><![CDATA[SequenceFlow]]></design:stencilid>
      </extensionElements>
    </sequenceFlow>
    <serviceTask id="serviceTask1" name="Set Variables" flowable:delegateExpression="${setVariable}">
      <extensionElements>
        <design:stencilid><![CDATA[ServiceTask]]></design:stencilid>
        <design:stencilsuperid><![CDATA[Task]]></design:stencilsuperid>
        <design:name-run><![CDATA[Set Variables]]></design:name-run>
      </extensionElements>
    </serviceTask>
    <sequenceFlow id="sequenceFlow2" sourceRef="serviceTask1" targetRef="serviceTask2">
      <extensionElements>
        <design:stencilid><![CDATA[SequenceFlow]]></design:stencilid>
        <design:conditionexpression><![CDATA[${object.validated == true}]]></design:conditionexpression>
      </extensionElements>
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${object.validated == true}]]></conditionExpression>
    </sequenceFlow>
    <serviceTask id="serviceTask2" name="Service task" flowable:delegateExpression="${variableSet}">
      <extensionElements>
        <design:stencilid><![CDATA[ServiceTask]]></design:stencilid>
        <design:stencilsuperid><![CDATA[Task]]></design:stencilsuperid>
        <design:name-run><![CDATA[Service task]]></design:name-run>
      </extensionElements>
    </serviceTask>
    <sequenceFlow id="sequenceFlow3" sourceRef="serviceTask2" targetRef="endNoneEvent1">
      <extensionElements>
        <design:stencilid><![CDATA[SequenceFlow]]></design:stencilid>
      </extensionElements>
    </sequenceFlow>
    <sequenceFlow id="sequenceFlow4" sourceRef="serviceTask1" targetRef="endNoneEvent1">
      <extensionElements>
        <design:stencilid><![CDATA[SequenceFlow]]></design:stencilid>
        <design:conditionexpression><![CDATA[${object.validated == false}]]></design:conditionexpression>
      </extensionElements>
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${object.validated == false}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_serialCondition">
    <bpmndi:BPMNPlane bpmnElement="serialCondition" id="BPMNPlane_serialCondition">
      <bpmndi:BPMNShape bpmnElement="startnoneevent1" id="BPMNShape_startnoneevent1">
        <omgdc:Bounds height="30.0" width="30.0" x="117.0" y="261.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endNoneEvent1" id="BPMNShape_endNoneEvent1">
        <omgdc:Bounds height="28.0" width="28.0" x="516.0" y="262.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="serviceTask1" id="BPMNShape_serviceTask1">
        <omgdc:Bounds height="80.0" width="100.0" x="176.0" y="236.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="serviceTask2" id="BPMNShape_serviceTask2">
        <omgdc:Bounds height="80.0" width="100.0" x="395.0" y="236.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow3" id="BPMNEdge_sequenceFlow3">
        <omgdi:waypoint x="494.95000000000005" y="276.0"></omgdi:waypoint>
        <omgdi:waypoint x="516.0" y="276.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow4" id="BPMNEdge_sequenceFlow4">
        <omgdi:waypoint x="226.0" y="315.95000000000005"></omgdi:waypoint>
        <omgdi:waypoint x="226.0" y="368.0"></omgdi:waypoint>
        <omgdi:waypoint x="530.0" y="368.0"></omgdi:waypoint>
        <omgdi:waypoint x="530.0" y="289.94993680813207"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow1" id="BPMNEdge_sequenceFlow1">
        <omgdi:waypoint x="146.94999793247734" y="276.0"></omgdi:waypoint>
        <omgdi:waypoint x="175.99999999999125" y="276.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow2" id="BPMNEdge_sequenceFlow2">
        <omgdi:waypoint x="275.95000000000005" y="276.0"></omgdi:waypoint>
        <omgdi:waypoint x="394.99999999992315" y="276.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
package com.dotmatics.register.tasks;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.stream.Stream;

@SuppressWarnings("WeakerAccess")
@Data
public final class EntityTree implements Serializable {

    private final Map<String, Object> map;

    private boolean validated;

    public EntityTree() {
        this(new HashMap<>());
    }

    public EntityTree(Map<String, Object> map) {
        this.map = map;
    }

    @SuppressWarnings("unchecked")
    public EntityTree(String json) throws IOException {
        this.map = new ObjectMapper().readValue(json, Map.class);
    }

    public String toJson() throws IOException {
        return new ObjectMapper().writeValueAsString(map);
    }

    public String getString(String key) {
        return String.valueOf(map.get(key));
    }

    public double getDouble(String key) {
        Object value = map.get(key);
        return value instanceof Float
                ? (float) value
                : (double) value;
    }

    public void put(String key, EntityTree entityTree) {
        map.put(key, entityTree.map);
    }

    public void put(String key, float value) {
        map.put(key, value);
    }

    public void put(String key, Object value) {
        map.put(key, value);
    }

    public EntityTree getSubTree(String key) {
        return optSubTree(key)
                .orElseThrow(() -> new RuntimeException("Key not found: " + key));
    }

    public Optional<EntityTree> optSubTree(String key) {
        Map<String, Object> subMap = getSubMap(key);
        return Optional.ofNullable(subMap)
                .map(EntityTree::new);
    }

    private Map<String, Object> getSubMap(String key) {
        return getSubMap(this.map, key);
    }

    public EntityTree path(String... keys) {
        return keys.length == 0
                ? this
                : traverse(keys);
    }

    private EntityTree traverse(String[] keys) {
        Map<String, Object> subMap = Stream.of(keys)
                .reduce(map, this::getSubMap, (m1, m2) -> m1);
        return new EntityTree(subMap);
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> getSubMap(Map<String, Object> map, String key) {
        return (Map<String, Object>) map.get(key);
    }

    public Stream<EntityTree> getSubtreesFromList(String key) {
        return getSubmapsFromList(key)
                .stream()
                .map(EntityTree::new);
    }

    @SuppressWarnings("unchecked")
    private List<Map<String, Object>> getSubmapsFromList(String key) {
        return (List<Map<String, Object>>) map.get(key);
    }

    public void addSubtreeToList(String key, EntityTree subTree) {
        BiFunction<String, Object, ?> op = (k, m) -> {
            List<Map<String, Object>> submaps = getSubmapsFromList(key);
            submaps.add(subTree.map);
            return submaps;
        };
        map.compute(key, op);
    }

    public Map<String, Object> toMap() {
        return map;
    }
}

but I even tried with a test class and it still didn’t work

package com.dotmatics.register.workflow.presentation.service;

import lombok.Data;

import java.io.Serializable;

@Data
public class TempEntityDefinition implements Serializable {
    String molFile;
    String inchi;
    Double mw;
    String formattedId;
    boolean validated;
}

using gradle:

implementation group: 'org.flowable', name: 'flowable-spring-boot-starter-rest', version: '6.4.2'

here is my full bpmn (Editing by hand)

<definitions id="definitions"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:flowable="http://flowable.org/bpmn"
             targetNamespace="http://www.flowable.org/processdef">
    <process id="REGISTER_COMPOUND" name="Register Compound" isExecutable="true">
        <startEvent id="registerCompoundStartEvent" name="Start"/>
        <serviceTask id="SaltStrippingDelegateServiceTask" name="Salt Stripping" flowable:class="com.dotmatics.register.workflow.flowable.delegate.SaltStrippingDelegateService">
            <extensionElements>
                <flowable:field name="documentMolPath">
                   <flowable:expression>
                           this is the path to the mol file in JSON document
                        </flowable:expression>
                </flowable:field>
            </extensionElements>
        </serviceTask>
        <serviceTask id="InchiDelegateServiceTask" name="Inchi" flowable:class="com.dotmatics.register.workflow.flowable.delegate.InchiDelegate"/>
        <serviceTask id="NeutralisationDelegateServiceTask" name="Neutralisation" flowable:class="com.dotmatics.register.workflow.flowable.delegate.NeutralisationDelegateService"/>
        <serviceTask id="NormalizationDelegateServiceTask" name="Normalization" flowable:class="com.dotmatics.register.workflow.flowable.delegate.NormalizationServiceDelegateService"/>
        <serviceTask id="ValidationDelegateServiceTask" name="Validation" flowable:class="com.dotmatics.register.workflow.flowable.delegate.ValidationDelegateService"/>
        <serviceTask id="PersistenceDelegateServiceTask" name="Persistence" flowable:class="com.dotmatics.register.workflow.flowable.delegate.PersistenceDelegateService"/>

        <sequenceFlow id="SaltStrippingFlow" sourceRef="registerCompoundStartEvent" targetRef="SaltStrippingDelegateServiceTask"/>
        <sequenceFlow id="InchiFlow" sourceRef="registerCompoundStartEvent" targetRef="InchiDelegateServiceTask"/>
        <sequenceFlow id="NeutralisationFlow" sourceRef="registerCompoundStartEvent" targetRef="NeutralisationDelegateServiceTask"/>
        <sequenceFlow id="NormalizationFlow" sourceRef="registerCompoundStartEvent" targetRef="NormalizationDelegateServiceTask"/>
        <sequenceFlow id="ValidationFlow" sourceRef="registerCompoundStartEvent" targetRef="ValidationDelegateServiceTask"/>
        <sequenceFlow id="PersistenceFlow" sourceRef="registerCompoundStartEvent" targetRef="PersistenceDelegateServiceTask">
            <conditionExpression xsi:type="tFormalExpression">
                ${entityDefinition.validated}
            </conditionExpression>
        </sequenceFlow>
        <endEvent id="registerCompoundEndEvent" name="End"></endEvent>
    </process>
</definitions>

BTW, is there a bpmn designer for Intellij?

Maybe it’s Lombok (though I wouldn’t think so). Can you try manually creating your getters and setters?

And, no there is not a Flowable BPMN designer for IntelliJ. I usually use the commercial web app (Design) but the open source Modeler works ok. Either way I run them in Docker containers.