Events

Overview

In the BPMN notation, events represent occurrences that happen during a business process. They are capable of initiating the start, continuation, or completion of activities within the process.

Events can be utilized to model various scenarios, such as the receipt of a message, the passage of time, or the occurrence of an error. By incorporating events into BPMN diagrams, users can effectively capture the behavior and flow of a business process.

The word 'event' is used in two different senses:

  1. When something occurs

  2. An element of BPMN diagram

Events can occur without being represented on the process diagram. For example, message events should be thrown programmatically.

Events Classification

First, events differ by a position they hold in the process, it may be the beginning, middle, or end. So we talk about start, intermediate, or end events.

The behavior of the event is defined by trigger activating it. For example, message or timer.

The process can consume or produce events. So, BPMN events in these roles are called 'catching' and 'throwing' events.

As well, some events can be attached to activities; such events are called 'boundary'.

Besides, the event may have a property to interrupt the process or let it go on. In this case, we talk about interruptible and non-interruptible events.

For your convenience, events classification is summarized in a table below:

Criteria Options

Position in the process

Start, Intermediate, End,

Trigger

None, Timer, Message, Signal, Error, Compensation

Role

Catching/Throwing

Is attached to activity?

Boundary

Can interrupt the process?

Interrupting or Non-interrupting

Position in the Process

Depending on its position in the process, events can be:

All events are visualized as a circle, where the style of a line (thin, double, or thick) says about a position of event in the process (start, intermediate, or end).

start end process

You can see an example of events representation in the XML below:

  <bpmn:process id="Process_1" isExecutable="true">
    <bpmn:startEvent id="start-event" name="Start event"> (1)
      <bpmn:outgoing>Flow_out_start</bpmn:outgoing>
    </bpmn:startEvent>
    . . .
    <bpmn:intermediateThrowEvent id="intermediate-event" name="Intermediate event"> (2)
      <bpmn:incoming>Flow_in</bpmn:incoming>
      <bpmn:outgoing>Flow_out</bpmn:outgoing>
    </bpmn:intermediateThrowEvent>
    . . .
    <bpmn:endEvent id="end-event" name="End event"> (3)
      <bpmn:incoming>Flow_in_end</bpmn:incoming>
    </bpmn:endEvent>

  </bpmn:process>
1  — Start event
2  — Intermediate event
3  — End event

Event Triggers

Event triggers in BPMN are used to indicate when a specific event should occur within a business process. There are several types of event triggers commonly used in BPMN, including the following:

Triggers can be activated manually or via API call.

Catching and Throwing Events

In BPMN 2.0, there exist two main event categories: catching and throwing events.

  • Catching: when process execution arrives at the event, it will wait for a trigger to happen. The type of trigger is defined by the inner icon or the type declaration in the XML. Catching events are visually differentiated from a throwing event by the inner icon that is not filled (usually white).

  • Throwing: when process execution arrives at the event, a trigger is fired. The type of trigger is defined by the inner icon or the type declaration in the XML. Throwing events are visually differentiated from a catching event by the inner icon that is filled (usually black).

For example, see below catching and throwing signal events:

sigtal catching throwing

Boundary Events

Boundary events are catching events that are attached to an activity (task, embedded subprocess or call activity). It can be more than one event attached to the activity. Boundary events are always catching.

Event subprocess can’t have boundary events.

In the XML, a boundary event is marked by special tag and has an attribute attachedToRef that refers to the activity it is attached to:

    <boundaryEvent id="Event_0gl2f4v" attachedToRef="Activity_1fsayqc">
      <timerEventDefinition id="TimerEventDefinition_0w9bip4" />
    </boundaryEvent>

Example

Boundary events can be attached to task, call activity or embedded subprocess.

boundary events example

While the activity is running, the event is listening for a designated type of trigger. When the trigger fired, the activity the event is attached to can be interrupted or not, depends on the type of event, interrupting or non-interrupting.

Process Interruption

The event can interrupt normal process execution. This is applicable to boundary events and start events in event subprocesses.

Boundary events of activities:
  • Interrupting — the activity is interrupted, and the sequence flow going out of the event is followed.

  • Non-interrupting — a new execution runs in parallel with the main activity and does not disrupt its flow.

boundary events

Interrupting event is visualized as a regular intermediate event, attached to the activity (task or subprocess), whereas a non-interrupting event has a dash-line border.

Non-interrupting event can trigger multiple times, and each time a new execution will start (a new token generated) until the task to be completed. For example, non-interrupting cyclic timer will fire every 5 minutes and send a notification to the user.

Type of behavior is defined by cancelActivity attribute. By default, it is set to true and the attribute usually omitted for interrupting events. For non-interrupting events its value is explicitly set to false.

For example, see non-interrupting timer event:

    <boundaryEvent id="Event_01" cancelActivity="false" (1)
        attachedToRef="user-task">
      <timerEventDefinition id="TimerEventDefinition_14a8e0l" />
    </boundaryEvent>
1  — Defines non-interrupting event.

Event Definitions

In BPMN, the messages and signals are a mechanism used to communicate between different elements within a business process or between processes. Both messages and signals play a crucial role in defining the interactions and dependencies between various elements in a BPMN diagram. Errors are similar to messages and signals, as they allow for the control of the process flow.

Messages and signals must be defined before they can be used in events. Error definitions in some cases can be omitted.

To define an event in Studio, open a process model, select nothing to access the process properties and find signal and message definition sections:

event definition

In the case of collaboration, select the desired participant (pool).

Defining a Message

To create a message definition, set its id and name:

define messages
Defining a Signal

To create a signal definition, set its id and name; besides, you must select a scope parameter, Global or Process instance:

define signal
Defining an Error

To create an error definition, set its id and name; besides, you may set Error code:

errors definition
XML Representation

Message, signal, and error definitions in the XML file are located usually between <process> and <diagram> sections.

</process>
<message id="green" name="Green" /> (1)
<message id="yellow" name="Yellow" />
<message id="red" name="Red" />
<signal id="ready" name="Ready" flowable:scope="global" /> (2)
<signal id="stop" name="Stop" flowable:scope="processInstance" />
<error id="failure" name="Failure" errorCode="500" />  (3)
<error id="fatal" name="Fatal" />  <bpmndi:BPMNDiagram id="BPMNDiagram_process">
1  — Message definitions
2  — Signal definitions
3  — Error definitions

If you plan to use the same messages and signals across various processes, you must create their definitions in each BPMN model.

Start Events of Event Subprocesses

Event subprocesses can have interrupting or non-interrupting start events.

  • Interrupting — when event subprocess ends, the main process to be terminated.

  • Non-interrupting — event subprocess executes in parallel and comes to its end, the main process continues.

interrupting non events subprocess

In the picture above, the first subprocess interrupts the main process when time is over. The second subprocess executes a service task and ends not affecting the main process.

Event Subscriptions

An event subscription is a mechanism that allows a process to wait for a specific event to occur before continuing its execution. Event subscription types are:

  • Message

  • Signal

  • Timer

  • Error

  • Compensation

Creating

There are two cases:

  • Start events —  Subscriptions are created at deployment time.

  • Intermediate and boundary events — Subscriptions are created when execution reaches the event.

Each event subscription can be configured with parameters that define how the event should be correlated with the process instance. This includes specifying event types, names, and any required correlation parameters that must match for the subscription to be triggered.

Storing

The event subscriptions are stored in the database, in the ACT_RU_EVENT_SUBSCR table. This table holds information about the event type, process instance ID, and any correlation parameters needed for message events.

Triggering

When the corresponding event occurs, (e.g., a message is received, or a timer expires), process engine checks the event subscriptions to find any that match the event criteria. For message events, the application must correlate the incoming message to the correct process instance using correlation parameters.


  1. Creating Event Subscriptions

    You can create event subscriptions for message, signal, and timer events programmatically. For example, you can start a process instance by sending a message:

    // Start a process instance with a message
    ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage("orderPlaced", processVariables);
  2. Querying Event Subscriptions

    You can query for existing event subscriptions to see which processes are waiting for specific events. For example:

    List<EventSubscription> messageSubscriptions = runtimeService.createEventSubscriptionQuery()
        .eventType("message")
        .list();
  3. Getting Event Subscriptions

    You can get a list of subscriptions using RuntimeService API. For example, signal subscriptions:

    // Query for all signal event subscriptions
    List<EventSubscription> signalSubscriptions = runtimeService.createEventSubscriptionQuery()
        .eventType("signal")
        .list();

    For other types of events, use "message", "error", and "compensate" respectively.

    For timers, use ManagementService:

    List<Job> timerJobs = managementService.createTimerJobQuery().list();
  4. Triggering Event Subscriptions

    You can trigger event subscriptions programmatically when the corresponding event occurs. For example, to trigger a message event:

    runtimeService.messageEventReceived("orderPlaced", executionId, processVariables);
  5. Deleting Event Subscriptions

    You can delete event subscriptions if they are no longer necessary. For example, to delete a specific event subscription:

    runtimeService.createEventSubscriptionQuery()
        .eventType("message")
        .processInstanceId(processInstanceId)
        .singleResult();
Handling Events with Listeners

See the Listeners section.

Start Events

A start event is the entry point of the process. When the engine tries to begin execution of the process, it searches for the start event in the BPMN model.

So, the process MUST have a Start event. Start events are always catching: conceptually, the event is (at any time) waiting until a certain trigger happens.

Start events can be of the following types:

Multiple Start Events

Although BPMN allows multiple start events, the process technically may have only one none start event. Otherwise, it will cause error at deployment. Don’t use more than one none start event like in the picture below:

multiple start none

However, it is possible to use multiple start events of other types:

multiple start events good

You can use several message (or signal) start events provided the messages (or signals) differ.

End Events

An end event signifies the end of a path in a process or subprocess. An end event is always throwing. There could be the following end events in Jmix BPM:

Multiple End Events

Formally, end event isn’t mandatory. The process ends when there are no activities to execute. But it is a good practice to finish each path of the process by the end event.

end event not mandatory

Don’t try to bring all flows to the single end event – it only makes your diagram messy.

end events examples

Multiple end events allow to analyze how processes ended.

multiple end events

None Events

None events are unspecified events, also called "blank" events.

None Start Event

A none start event technically means that the trigger for starting the process instance is unspecified. This means that the engine cannot guess when the process instance must be started.

Embedded subprocess always has a none start event.
Graphical Notation

A none start event is visualized as a circle with no inner icon (in other words, no trigger type).

none start event
Properties

None start event has two specific properties:

  • Process variables — provide information about parameters that are used for starting the process via API.

  • Form — defines a user interface when the process is to be started manually.

start event properties

You can define process variables in the start event by clicking a create link in the BPMN Inspector panel:

create process variables in start event

Then type a variable name and press 'Enter':

create variable window

By default, a new variable is created with a String type, but you can change its type to the desired one.

edit process variable in start event

Process variables defined here wouldn’t be created in the process instance. They must be initialized some way. For example, with script task.

If process variables are created before the form, they will be added to form automatically.

About the Form settings see the details in the Process Forms section.

XML Representation

The XML representation of a none start event is the normal start event declaration without any sub-element (other start event types all have a sub-element declaring the type).

<startEvent id="startEvent1" name="Start"> (1)
  <extensionElements>
    <jmix:processVariables>
      <jmix:processVariable name="invoiceId" type="string" /> (2)
    </jmix:processVariables>
    <jmix:formData type="no-form" /> (3)
  </extensionElements>
  <outgoing>Flow_0h77bcd</outgoing>
</startEvent>
1  — Start event definition.
2  — Process variable.
3  — Here may be a form definition.

Triggering None Start Event via API

The none start event is used when the process instance is started through the API by calling one of the startProcessInstanceByXXX methods.

For example,

ProcessInstance processInstance = runtimeService
        .startProcessInstanceByKey("process-id");

Flowable API uses the term 'process definition key' that is equivalent to 'process id' in Jmix Studio.

See details in the Flowable API section.

Intermediate None Event

Intermediate none events can be used to indicate some state achieved in the process. The engine itself doesn’t do anything in the event, it just passes through it.

Graphical Notation

An intermediate none event is visualized as a circle with a double outline and no inner icon (in other words, no trigger type).

intermediate none event
Properties

Intermediate none event has no specific properties.

XML Representation

The XML representation of an intermediate none event is the event declaration by intermediateThrowEvent without any sub-element.

  <intermediateThrowEvent id="IntermediateEvent" />

Example

Intermediate none events are especially useful for monitoring to understand how the process is doing, for example, as milestones or key performance indicators (KPIs).

none intermediate event example

None End Event

A none end event is a type of end event that signifies the completion of a process without any specific outcome or result. It does not trigger any subsequent activities or flows in the process.

Graphical Notation

None end event is visualized as a circle with a thick outline and no inner icon.

none end event
Properties

None end event has no specific properties.

XML Representation
    <endEvent id="end-event" name="End">
      <incoming>Flow_0qwib28</incoming>
    </endEvent>

Timer Events

Timer events in BPMN are events that are triggered based on a predefined time or duration. Timer events can be used to control the flow of a process by specifying when certain activities should be executed.

There are two types of timer events:

As well, timers can be used as boundary events, interrupting or non-interrupting.

timer events example

Timer Start Event

Timer start event is used to create process instances at a given time. It can be used for processes that should start only once or in specific time intervals.

Embedded subprocess cannot have a timer start event, but event subprocess can.

Graphical Notation

A timer start event is visualized as a circle with clock inner icon.

timer start event
Properties

Timer start event has a specific property Timer Definition that defines its type and expression. See timer types for details.

timer start event properties

XML Representation

The XML representation of a timer start event is the normal start event declaration, with the timer definition sub-element. Please refer to timer definitions for configuration details.

<startEvent id="theStart">
  <timerEventDefinition> (1)
        . . . (2)
  </timerEventDefinition>
</startEvent>
1  — Timer event definition.
2  — Definition child element.

Using Timer Start Event

In this example, the main process starts by timer event. And it has two event subprocesses also starting by timers. The first one is non-interruptible, it can do some activities at a certain moment from the process start. The second event subprocess has an interruptible timer, that means the main process will be stopped when this timer event fires.

timer start event example
Don’t use initiator variable in a process with timer start event, it causes execution error. Unless you define and set its value programmatically.

Timer Intermediate Event

Timer intermediate event acts as a stopwatch. When an execution arrives at event, a timer is started. When the timer fires after a specified interval or a date coming, the process continues.

Timer intermediate event is a waiting state.

Graphical Notation

A timer intermediate event is visualized as an intermediate catching event, with the timer icon on the inside.

timer untermediate catch event
Properties

A timer intermediate event has the same properties as timer start event.

intermediate timer properties
XML Representation

A timer intermediate event is defined as an intermediate catching event. The specific type sub-element is, in this case, a timerEventDefinition element.

<intermediateCatchEvent id="timer">
  <timerEventDefinition>
    <timeDuration>PT8H</timeDuration> (1)
  </timerEventDefinition>
</intermediateCatchEvent>
1  — Timer type, for example, duration.

Timer Types

The system allows selecting one of three types of timer:

timer types
Duration

 — fires after the specified time period.

Cycle

 — event repeats a certain number of times or according to Cron expression.

Date

 — fires at specified date; ignored if date is in the past.

For start timer event duration counts from the moment the process was deployed to server.

Setting Time

There are two ways of setting time parameter in timers:

Standard ISO 8601

ISO 8601 is an international standard covering the worldwide exchange and communication of date and time-related data.

Examples:
2035-06-17T07:42:14

 — a date of year 2035, 17 of June, time 7 hours 42 minutes 14 seconds

2050:01:01

 — a date of year 2050, 1 of January, 00 hours 00 minutes

PT30D

 — duration of thirty days

PT10M

 — duration of ten minutes

P3Y6M4DT12H30M5S

 — duration of three years, six months, four days, twelve hours, thirty minutes, and five seconds

R3PT10H

 — cyclic period recurring three times every ten hours

Don’t use very short periods of time, smaller than 3 seconds. BPM isn’t a real-time system.

See ISO 8601 standard site for the details.

Cron Expressions

Cron is a time-based job scheduling system used in Unix-like operating systems. It allows users to schedule tasks or commands to run at specific times, dates, or intervals. The term "cron" comes from the word "chronos," which means time in Greek.

You can specify time cycle using cron expressions; the example below shows trigger firing every 5 minutes, starting at full hour:

0 0/5 * * * ?

In Timer intermediate event Cron expressions can be used ONLY with a Cyclic timer type. Otherwise, it’d be an error when you try to deploy the process.

Message Events

Message events are events that reference a Defining a Message. They are used to model communication between different parts of a business process or between different processes. Message events represent the sending (throwing) or receiving (catching) of messages within a process flow.

There are two types of message events:

As well, message events can be used as boundary events.

message events types

Message throwing events (intermediate, end) are not supported in Jmix BPM. See workaround.

Message Start Event

A message start event can be used to start a process instance using a named message.

Graphical Notation

A message start event is visualized as a circle with a message event symbol. The symbol is unfilled, to represent the catching (receiving) behavior.

message start event
Properties

Message start event must have filled a Message property referring to the existing message definition. This is mandatory, otherwise it will cause an error at deployment.

start message properties
XML Representation

The XML representation of a message start event is the normal start event declaration with a messageEventDefinition child-element:

    <startEvent id="Message_start_event>
      <messageEventDefinition id="MessageEventDefinition_invoice"
            messageRef="new-invoice-message" /> (1)
    </startEvent>
1  — reference to the message definition.

Using Message Start Event

A process can have one or more message start events, but messages must be different.

When a process is deployed, the engine creates a message subscription for each message start event. Any subscriptions from the previous version of the process will be closed.

The name of the message start event must be unique across all deployed process definitions. If a process definition containing one or more message start events references a message with the same name as a message start event already deployed by a different process definition, process engine will throw an exception upon deployment.

Triggering Message Start Event Programmatically

When starting a process instance, a message start event can be triggered using startProcessInstanceByMessage methods on the RuntimeService.

In API call use exactly message name, not id. For example, we have such message definition:

<message id="green" name="Green" />

Then, invoke API method the following way:

runtimeService.startProcessInstanceByMessage("Green");

Message start events are not supported on embedded subprocesses.

Message Intermediate Catching Event

An intermediate catching message event catches messages with a specified name.

Graphical Notation

An intermediate catching message event is visualized as a typical intermediate event (circle with double outline), with the message icon inside. The message icon is unfilled to indicate its catch semantics.

message catch event
Properties

An intermediate catching message event has the same properties as a message start event.

catch message event properties
XML Representation

A message intermediate event is defined as an intermediate catching event. The specific type sub-element is a messageEventDefinition element.

<intermediateCatchEvent id="catch-message-event"
    name="Catch message">
  <messageEventDefinition id="MessageEventDefinition_16bx9rl"
    messageRef="message-one" />
</intermediateCatchEvent>

When an intermediate message catch event is entered, a corresponding message subscription is created. The process instance stops at this point and waits until the message is received. After that, the catch event is completed and the execution continues.

Message intermediate catching event is a waiting state. In this example, the process will wait for a message after the completion of Activity 1, and Activity 2 will be executed once the message is received.

message intermediate example

Boundary Message Events

An attached intermediate catching message on the boundary of an activity, or boundary message event for short, catches messages with the same message name as the referenced message definition.

Graphical Notation

Boundary message events can be interruptible (with solid double outline) or non-interruptible (with dashed double outline).

boundary message event
Properties

Boundary message events have the same properties as a message start event.

boundary message properties
XML Representation

Boundary events are defined as child elements of the activity they attached to. Message events must have messageRef attribute referring to existing message definition.

Non-interruptible message event has an attribute cancelActivity=false.

<task id="Activity_task" name="Task" /> (1)
<boundaryEvent id="interruptible-message-event" name="Message 1" (2)
    attachedToRef="Activity_task">
  <messageEventDefinition id="MessageEventDefinition_1"
    messageRef="messageOne" />
</boundaryEvent>
<boundaryEvent id="non-interruptible-message-event" name="Message 2" (3)
    cancelActivity="false" (4)
    attachedToRef="Activity_task">
  <messageEventDefinition id="MessageEventDefinition_2" messageRef="messageTwo" />
</boundaryEvent>
1  — A task boundary message events attached to.
2  — Interruptible message event.
3  — Non-interruptible message event.
4  — cancelActivity attribute.

Using Boundary Message Events

Message events can be used as boundary events, interruptible or non-interruptible:

message boundary events

The activity may have several boundary message events.

Signal Events

Signal events are events that reference a signal definition. Broadcasting a signal will trigger all signal events matching the name of the broadcast signal. Signals have a scope, it can be Global or Process instance.

signal events

There are the following signal events in Jmix BPM:

Signal end event isn’t supported. Use workaround.

Signal Start Event

A signal start event can be used to start a process instance using a named signal definition. The process can have one or more signal start events, but signal definitions must differ.

Graphical Notation

A signal start event is visualized as a circle with a signal event symbol. The symbol is unfilled, to represent the catching (receiving) behavior.

signal start event
Properties

A signal start event has a specific property Signal that refers to the certain signal definition. It must be filled and refer to existing signal definition, otherwise it causes error during deployment.

signal start event properties
XML Representation

The XML representation of a signal start event is the normal start event declaration with a signalEventDefinition child-element:

    <startEvent id="signal-start-event" name="Start">
      <signalEventDefinition id="SignalEventDefinition_00paqo6" (1)
        signalRef="signal-one" /> (2)
      <outgoing>Flow_0h77bcd</outgoing>
    </startEvent>
1  — Event declaration.
2  — Reference to signal definition.

Using Signal Start Event

When a process is deployed, the engine creates a signal subscription for each signal start event. Subscriptions of the previous version of the process would be closed.

It is allowed to have many process definitions with the signal start event referred to the same signal. When the signal fires, all subscriptions be activated and processes started.

The signal can be 'fired' from within a process instance using the intermediate signal throw event or through the API methods signalEventReceived.

In API call use exactly signal name, not id. For example, we have such signal definition:

<signal id="ready" name="Ready" flowable:scope="global" />

Then, invoke API method the following way:

runtimeService.signalEventReceived("Ready");

Signal start events are not supported in embedded subprocesses.

Signal Intermediate Catching Event

Signal intermediate catching event catches signals with the same signal name as the referenced signal subscription. Signal intermediate catching event is a wait state.

Graphical Notation

An intermediate signal catch event is visualized as a typical intermediate event (circle with double outline), with the signal icon inside. The signal icon is unfilled to indicate its catch semantics.

signal intermediate catching event
Properties

An intermediate signal catch event properties are the same as for a signal start event.

signal catch event properties
XML Representation
<intermediateCatchEvent id="signal-catch-event" name="Catch signal">
      <incoming>Flow_0qwib28</incoming>
      <outgoing>Flow_1itm8do</outgoing>
      <signalEventDefinition id="SignalEventDefinition_1" (1)
        signalRef="signal-one" /> (2)
    </intermediateCatchEvent>
1  — Signal event declaration.
2  — Reference to the signal definition.

Using Signal Catch Event

Contrary to other events, such as an error event, a signal is not consumed if it is caught. If you have two active signal boundary events catching the same signal event, both boundary events are triggered, even if they are part of different process instances.

Signal Intermediate Throwing Event

An intermediate throwing signal event throws a signal event for a defined signal. The signal is broadcast to all catching signal events, starting and intermediate (signal subscriptions).

Graphical Notation

An intermediate signal throw event is visualized as a typical intermediate event (circle with double outline), with the signal icon inside. The signal icon is filled to indicate its throw semantics.

signal throwing event
Properties

An intermediate signal catch event properties are the same as for a signal start event, but its semantics differs — throwing instead of catching.

signal throw event properties

Signals Publication Mode

Signals can be published synchronously or asynchronously.

  • In the default configuration, the signal is delivered synchronously. This means that the throwing process instance waits until the signal is delivered to all catching process instances. The catching process instances are also notified in the same transaction as the throwing process instance, which means that if one of the notified instances produces a technical error (throws an exception), all involved instances fail.

  • A signal can also be delivered asynchronously. In this case, it is determined which handlers are active at the time the throwing signal event is reached. For each active handler, an asynchronous notification message (Job) is stored and delivered by the JobExecutor.

XML Representation

A signal intermediate event is defined as an intermediate throwing event. The specific type sub-element is, in this case, a signalEventDefinition element.

<intermediateThrowEvent id="Event_sync">
  <signalEventDefinition id="SignalEventDefinition_14tnjbf"
    signalRef="my-signal" /> (1)
</intermediateThrowEvent>


<intermediateThrowEvent id="Event_async">
  <signalEventDefinition id="SignalEventDefinition_14tnjbf"
    signalRef="my-signal" flowable:async="true" /> (2)
</intermediateThrowEvent>
1  — Attribute async is omitted, implicitly it is false, the signal will be published synchronously.
2  — Signal be published asynchronously.

Error Events

Error events in BPMN are typically used to model exceptional or error situations that may arise during the execution of a process. They can be attached to activities or subprocesses within a BPMN diagram to define how errors should be handled, such as by triggering error handling routines, logging the error, or notifying stakeholders.

There are the following types of error events:

Error Start Event

An error start event can be used to trigger an event subprocess. It cannot be used for starting a process instance. An error start event is always interrupting.

Graphical Notation

An error start event is visualized as a circle with an error event symbol. The symbol is unfilled, to represent the catching (receiving) behavior.

error start event
Properties

An error start event has a specific property — Error, that must refer to some error definition.

Unlike messages and signals, reference to error definition isn’t mandatory. If in the event the error definition is omitted, the subprocess will start for every error event that occurs.

error start event properties
XML Representation

The XML representation of an error start event is the normal start event declaration with an errorEventDefinition child-element:

  <startEvent id="error-event" name="Error">
    <errorEventDefinition id="ErrorEventDefinition_1" (1)
        errorRef="failure" /> (2)
  </startEvent>
1  — Error event declaration.
2  — Reference to error definition.

Example

In this example, the first task generates BPMN error programmatically. At this moment the event subprocess launches and after its completion, the main process is to be terminated.

error start event example

Error Boundary Event

An error boundary event catches errors that are thrown within the scope of the activity on which it is defined.

Graphical Notation

An error boundary event is visualized as a typical intermediate event (circle with double outline) on the boundary, with the error icon inside. The error icon is unfilled to indicate its catch semantics.

error boundary event
Properties

An error boundary event has the same properties as error start event.

error boundary event properties
XML Representation
<serviceTask id="Activity_1" name="Check error"
. . .
</serviceTask>
<boundaryEvent id="error-boundary-event" name="Error"
    attachedToRef="Activity_1">
  <errorEventDefinition id="ErrorEventDefinition_1"
    errorRef="failure" />
</boundaryEvent>

Error End Event

When process execution arrives at an error end event, the current process path ends and an error is thrown.

Graphical Notation

An error end event is visualized as a typical end event (circle with a thick border), with the error icon inside. The error icon is filled to indicate its throwing semantics.

error end event

Properties

An error end event has a specific property Error that isn’t mandatory. When filled, it refers to the existing error definition.

error end event properties
XML Representation

An error end event is represented as an end event, with an errorEventDefinition child element.

<endEvent id="Event_01" name="Error">
  <incoming>Flow_1i3jqxp</incoming>

  <errorEventDefinition id="ErrorEventDefinition_11xfxfw" (1)
    errorRef="failure" /> (2)
</endEvent>
1  — Declaring error event
2  — Reference to the error definition, it can be omitted.

Using Error End Event

The error end event is a throwing event and must have the corresponding catching event. It can be an error boundary event if the error end event belongs to a subprocess.

error end event in subprocess

Or error start event if there is an event subprocess.

error end event with event subprocess

Using error end event without catching error event causes an exception at runtime.

error end event bad example

See more it the Error Handling section.

Compensation Events

Compensation events help with undoing steps that were already successfully completed in the case that their results are no longer desired and need to be reversed.

There are types of compensation events:

Compensation Intermediate Throw Event

Compensation intermediate throwing event can be used to trigger compensation.

Triggering Compensation

Compensation can either be triggered for a designated activity or for the scope that hosts the compensation event. Compensation is performed through execution of the compensation handler associated with an activity.

When compensation is thrown for an activity, the associated compensation handler is executed the same number of times the activity completed successfully.

If compensation is thrown for the current scope, all activities within the current scope are compensated, which includes activities on concurrent branches.

Compensation is triggered hierarchically: if the activity to be compensated is a subprocess, compensation is triggered for all activities contained in the subprocess. If the subprocess has nested activities, compensation is thrown recursively. However, compensation is not propagated to the "upper levels" of the process: if compensation is triggered within a subprocess, it is not propagated to activities outside of the subprocess scope. The BPMN specification states that compensation is triggered for activities at "the same level of subprocess".

In Flowable, compensation is performed in reverse order of execution. This means that whichever activity completed last is compensated first, and so on.

The intermediate throwing compensation event can be used to compensate transaction subprocesses that competed successfully.

Graphical Notation

An intermediate compensation throw event is visualized as a typical intermediate event (circle with double outline), with the compensation icon inside. The compensation icon is filled to indicate its throw semantics.

compensation throwing event
Properties

A compensation throw event has no specific properties.

compensation throwing event properties
XML Representation

A compensation intermediate event is defined as an intermediate throwing event. The specific type sub-element is, in this case, a compensateEventDefinition element.

<intermediateThrowEvent id="throwCompensation">
  <compensateEventDefinition id="CompensateEventDefinition_0s3nsqo" />
</intermediateThrowEvent>

In addition, the optional argument activityRef can be used to trigger compensation of a specific scope or activity:

<intermediateThrowEvent id="throwCompensation">
    <compensateEventDefinition id="CompensateEventDefinition_0s3nsqo"
        activityRef="bookHotel" /> (1)
</intermediateThrowEvent>
1  — Triggering compensation for specific activity.

Example

If compensation is triggered within a scope that contains a subprocess, and that subprocess includes activities with compensation handlers, the compensation will only be propagated to the subprocess if it has completed successfully at the time the compensation is thrown.

If some activities nested within the subprocess have already completed and have attached compensation handlers, those handlers will not be executed if the subprocess itself has not yet completed. Consider the following example:

compensation example

In this process, we have two concurrent executions: one for the embedded subprocess and another for the "charge credit card" activity. Let’s assume both executions have started, and the first concurrent execution is currently waiting for the user to complete the "review bookings" task.

The second execution carries out the "charge credit card" activity, during which an error occurs, triggering the "cancel booking" event to initiate compensation.

At this point, the parallel subprocess has not yet completed, meaning the compensation event is not propagated to it, and consequently, the "cancel hotel booking" compensation handler is not executed.

If the user task (and, consequently, the embedded subprocess) is completed before the "cancel booking" action is performed, compensation will be propagated to the embedded subprocess.

Compensation Boundary Event

Compensation boundary event can be used to attach a compensation handler to an activity.

The compensation boundary event must reference a single compensation handler using a directed association.

A compensation boundary event has a different activation policy from other boundary events. Other boundary events, such as the signal boundary event, are activated when the activity they are attached to is started. When the activity is finished, they are deactivated and the corresponding event subscription is canceled.

The compensation boundary event is different. The compensation boundary event is activated when the activity it is attached to completes successfully. At this point, the corresponding subscription to the compensation events is created. The subscription is removed either when a compensation event is triggered or when the corresponding process instance ends. From this, it follows:

  • When compensation is triggered, the compensation handler associated with the compensation boundary event is invoked the same number of times the activity it is attached to completed successfully.

  • If a compensation boundary event is attached to an activity with multiple instance characteristics, a compensation event subscription is created for each instance.

  • If the process instance ends, the subscriptions to compensation events are canceled.

The compensation boundary event is not supported on embedded subprocesses.

Graphical Notation

A compensation boundary event is visualized as a typical intermediate event (circle with double outline) on the boundary, with the compensation icon inside. The compensation icon is unfilled to indicate its catching semantics. In addition to a compensation boundary event, the following figure shows a compensation handler associated with the boundary event using a unidirectional association.

The compensation boundary event must reference a single compensation handler using a directed association.

compensation boundary event
XML Representation

A compensation boundary event is defined as a typical boundary event:

<boundaryEvent id="Event_1" attachedToRef="Activity_1">
  <compensateEventDefinition id="CompensateEventDefinition_05" />
</boundaryEvent>

. . .

<association id="Association_02zt79e"
associationDirection="One"
sourceRef="Event_1" targetRef="Activity_1" />

Cancel Events

Cancel events are used in transaction subprocesses only. They are not available in the palette until you are in a transaction subprocess.

There are two types of cancel events:

Cancel End Event

The cancel end event can only be used in combination with a BPMN transaction subprocess. When the cancel end event is reached, a cancel event is thrown which must be caught by a cancel boundary event. The cancel boundary event then cancels the transaction and triggers compensation.

Graphical Notation

A cancel end event is visualized as a typical end event (circle with thick outline), with the cancel icon inside. The cancel icon is completely black, to indicate its throwing semantics.

cancel end event
XML Representation

A cancel end event is represented as an end event, with a cancelEventDefinition child element.

<endEvent id="myCancelEndEvent">
    <cancelEventDefinition />
</endEvent>

Cancel Boundary Event

An attached intermediate catching cancel event on the boundary of a transaction subprocess, or boundary cancel event for short, is triggered when a transaction is canceled.

When the cancel boundary event is triggered, it first interrupts all active executions in the current scope. Next, it starts compensation for all active compensation boundary events in the scope of the transaction.

Compensation is performed synchronously; in other words, the boundary event waits before compensation is completed before leaving the transaction. When compensation is completed, the transaction subprocess is left using any sequence flows running out of the cancel boundary event.

  • Only a single cancel boundary event is allowed for a transaction subprocess.

  • If the transaction subprocess hosts nested subprocesses, compensation is only triggered for subprocesses that have completed successfully.

  • If a cancel boundary event is placed on a transaction subprocess with multi instance characteristics, if one instance triggers cancellation, the boundary event cancels all instances.

Graphical Notation

A cancel boundary event is visualized as a typical intermediate event (circle with a double outline) on the boundary, with the cancel icon inside. The cancel icon is unfilled to indicate its catching semantics.

cancel boundary event
XML Representation

A cancel boundary event is defined as a typical boundary event:

<boundaryEvent id="boundary" attachedToRef="transaction" >
    <cancelEventDefinition />
</boundaryEvent>

As the cancel boundary event is always interrupting the cancelActivity attribute is not required.

Terminate end event

When a terminate end event is reached, all executions of the current process instance or subprocess will be terminated.

Graphical Notation

A cancel end event visualized as a typical end event (circle with thick outline), with a full black circle inside.

terminate end event
XML Representation

A terminate end event is represented as an end event, with a terminateEventDefinition child element.

<endEvent id="myEndEvent >
    <terminateEventDefinition  flowable:terminateAll="true">
    </terminateEventDefinition>
</endEvent>

The terminateAll attribute is optional (and false by default).

terminate end event example

Using Terminate End Event

In this example, we can see two user tasks executed in parallel. If the task #2 to be completed first, the execution arrives to the terminate end event. At this moment, task #1 will be deleted even it is still active.

terminate end event example 2

In the next example, the terminate end event is in a subprocess. When it will be reached, it affects only subprocess. So, task #1 will be deleted if it is active, subprocess be terminated, and the main process be continued a normal way.

BPMN Events Coverage

In Jmix BPM, not all BPMN 2.0 events are supported, and those that are not supported are marked in pink. This indicates that while the BPMN 2.0 standard defines a wide range of events, Jmix BPM integrates the Flowable BPM engine, which may not implement every event type available in the standard.

jmix events

Not supported events:

  • Message throwing, intermediate and end event

  • Signal throwing end event

  • Compensation end event

  • Escalation events (all types)

  • Conditional events (all types)

  • Link events (all types)

Be careful when importing BPMN models from 3rd party design tools: not supported events can be shown on the diagram but may cause error at runtime.

Workarounds for Unsupported Events

In this section, you’ll find recipes how to implement a desired process logic for elements that are not supported in Jmix BPM.

Message Throwing Event

First, use signals instead of messages everywhere it is possible. In most cases, these types of events are interchangeable.

signal instead of message

Second, use a service task with the API call.

throw message workaround 1

Service task can be implemented as Spring bean, for example:

@Component(value = "smpl_MyService")
public class MyService {

    @Autowired
    private RuntimeService runtimeService;

    public void sendMessage(String messageName, String executionId) {
        runtimeService.messageEventReceived(messageName, executionId);
    }
}

Signal Throwing End Event

Use the combination of signal throwing intermediate event and none_end_event:

workaround signal end event

Compensation End Event

compensation end event workaround

Escalation Events

It is possible to use BPMN error events instead of escalation in certain scenarios. Error events in BPMN are used to handle unexpected errors or exceptions that occur during the execution of a process. They can be used to model error handling and recovery mechanisms within a process.

Escalation events, on the other hand, are used to escalate a problem to a higher level in the organization or process hierarchy. They are typically used when a problem cannot be resolved at the current level and needs to be escalated for further action.

So, escalation events are technically very close to error events.

workaround escalation events

Conditional Events

The conditional event defines an event which is triggered if a given condition is evaluated to true. It can be used as start event of an event subprocess, as intermediate event and boundary event. The start and boundary event can be interrupting and non interrupting.

You can implement similar logic by using execution listeners in combination with signal or message event.

workaround conditional events

Don’t use link events.

Link events can appear on the diagram when importing the XML file from 3rd party tools like Camunda Modeler.