When Process Definitions are deployed as Business Services in a Cloud environment, client applications or BAMOE Management Console users can create Process Instances that follow the sequence flow defined in the Process Definition. Some Process Instances may run for weeks or months and be in waiting states, due to Timers or User Tasks. When deploying a new version of the Process Definition to running Business Services, you can use the BAMOE Process Instance Migration (PIM) Add-on to manage Process Instances in waiting states, and avoid them following obsolete Process Definitions.
Introduction to BAMOE Process Instance Migration (PIM) Add-on
The BAMOE Process Instance Migration (PIM) Add-on and its user interface enable you to manage the migration of in-flight Process Instances to a new Process Definition version or to a completely different Process Definition via:
-
REST API, BAMOE Management Console in the Runtime environment,
-
BAMOE Quarkus Dev UI extension or BAMOE Spring Boot Web Console in Dev environment.
By mapping the original Process Definition nodes to updated Process Definition nodes, Process Instances can transition to the new sequence flow and adapt to changes in their definitions over time without losing their current state or requiring a restart.
This functionality enables you to:
-
To keep long running processes aligned with evolving business rules and business needs.
-
To reduce operational risk through evolution of obsolete workflows.
-
To maintain flexibility to adapt your processes without restarting Process Instances.
Guidelines and Process
A migration plan should be developed on a mirror of your production system. Before doing the actual migration, you should backup your database and plan downtime for your users to avoid conflicting changes on the same processes. Performing a Process Instance Migration on a live system could result in errors, and even data corruption. Only restore access once the migration has finished executing.
The hierarchy between a Process and its subprocesses are preserved during migration. When a Process Instance is migrated all its subprocesses, including nested ones, are also automatically migrated. Alternatively, if you attempt to migrate a subprocess without migrating its parent process, the migration will fail.
|
Note
|
The new version of the Process Definition must be compatible with the previous version. If this is not the case you may have errors during the next interaction with Process Instances that have been migrated. In this situation you will need to use PIM to migrate Process Instances again to a compatible data model. |
The process to set up plan and migrate Process Instances to new Process Definitions in your production system is the following:
-
Include the BAMOE PIM Add-on dependency in your Business Service POM.
|
Note
|
If you are upgrading from 9.3.0 ensure you have run the database migration scripts (see Upgrading your stateful Workflow database) to add required PIM tables (see Reference → Stateful Workflows subsystem db tables) |
-
Create your plan by defining the source and target Process Definitions and explicit node mappings. This is easier to do in BAMOE Management Console.
-
Test your migration plan on a duplicate of your production system.
-
When you are ready to migrate your production system, ensure you have isolated it from user interactions and that you have a recent backup.
-
Execute your PIM plan to migrate the Process Instances that are in a wait state, that match the defined criteria, to the new Process Definitions. + You can manage this step either in BAMOE Management Console or via REST API. + During migration, the state of a Process Instance is preserved and Process and Task variables, Jobs schedules and SLAs remain unchanged.
If you are using Quarkus your migrations can take time due to heavy database updates. You can configure the following transaction timeout in application.properties:
bamoe.pim.transaction-timeout=<seconds>
If you are experiencing slowness during the PIM execution with PostgreSQL, make sure that database statistics are up-to-date by running ANALYZE or disable nested loop joins in the database:
enable_nestloop=off
For more information on using the BAMOE Management Console to migrate Process Instances see Management Console → Process Instance Migration
For more information on using the BAMOE PIM Add-on API to migrate Process Instances to a new Process Definition see Process to migrate via REST API
What happens during migration?
PIM does more than just switch Process Definitions, it ensures consistency across the stateful process subsystems in the following ways:
- Subsystem adaptation
-
Migrates process nodes and updates associated elements in subsystems like Data-Index and User Tasks (Jobs Service does not require adaptation). After migration, the Business Service remains fully functional through both REST APIs and UIs.
- Active elements only
-
Only active elements (node instances, User Tasks, etc.) are migrated. Nodes that are no longer active will not be migrated.
- Data handling
-
Process Instances contain information (data) about the entities in the Workflow, necessary to execute the Workflow (Process or Task variables), and that PIM does not migrate. If your new Process Definition contains new variables, they will be initialized with an empty value. If your data model changes, you must ensure backward compatibility, otherwise, PIM cannot properly migrate Process Instances, and you will need to use alternative strategies, such as draining out existing instances.
Mapping rules and limitations
To maintain process integrity after migration, PIM has some strict node mapping rules, applied via implicit or explicit node mappings.
- Implicit node mapping
-
All nodes that can be on a waiting state in the source process definition must exist in the target process definition with their original node ID.
- Explicit node mapping
-
When implicit mapping is not satisfied you need to provide explicit node mappings.
The following table describes the rules for Explicit Node mappings:
Explicit node mapping rules |
Description |
Nodes type |
Only nodes that can put the Process Instance in a waiting state (catch events, user tasks, work items, call activities/subprocesses) should be included in the explicit mapping list, since only active elements are migrated. |
Same family mapping |
Nodes must be mapped to nodes of the same type. For example, a User Task cannot be mapped to an event. |
Removed nodes |
If a node is removed in the target Process Definition, the source node must be explicitly mapped to a node of the same family in the target Process Definition. |
User Task limitation |
Tasks in BPMN are immutable in the User Task subsystem. To modify task details during migration, define a new task with a different ID and node ID in the target Process Definition and map accordingly. |
Implicit mapping must become explicit |
If a node must be explicitly mapped in the plan, any implicit mapping must become explicit. In this case, the BAMOE PIM Add-on automatically converts implicit mappings to explicit, adding them to the plan. |
Process Instance migration through the PIM REST API
If you want to automate or integrate migration in a larger process, rather than complete the migration using the UI, BAMOE exposes a REST API for Process Instance Migration, see Management APIs Process → Process Instance Migration APIs.
Managing migration plans
You can use the following endpoints to create and manage migration plans with the PIM Add-on:
-
Create a new migration plan that defines how process instances move from a source process to a target process using
POST /pim/plan, defining the following payload fields:-
sourceProcessId (String) - ID of the source process.
-
sourceProcessVersion (String) - Version of the source process.
-
targetProcessId (String) - ID of the target process.
-
targetProcessVersion (String) - Version of the target process.
-
nodeMapping (List) - Optional list of node mappings (sourceId → targetId).
For example:
{ "sourceProcessId": "hiring", "sourceProcessVersion": "1.0", "targetProcessId": "hiring2", "targetProcessVersion": "1.0", "nodeMapping": [ {"sourceId": "_B8C4F63C-81AD-4291-9C1B-84967277EEF6", "targetId": "_CBB6BF5D-21DA-43D2-A20B-C361694AF7AE"}, {"sourceId": "_B4BB21C5-7BCA-47DA-A688-2F37BC6B76A7", "targetId": "_C7DBD2B3-1744-4844-8B3D-D23CAF9D2436"} ] }The endpoint returns the plan details, validation status, and warnings/errors if any.
-
-
You can use
GET /pim/plan/{planId}to obtain details of a specific migration plan, including mappings and validation results. -
You can use
DELETE /pim/plan/{planId}to remove a migration plan that is not currently in use. -
You can use
GET /pim/plansto retrieve all migration plans, and optionally filter using thesourceProcessIdandtargetProcessIdas query parameters.
Managing migrations
You can use the following endpoints to execute and retrieve information on migrations with the PIM Add-on:
You can use POST /pim/migration to execute the migration of active Process Instances from the source to the target Process Definition using the specified migration plan.
-
If you want full migration where all active Process Instances of the source process will be migrated, do not specify any Process Instance IDs
-
If you want bulk migration to migrate a subset of Process Instances, provide a list of Process Instance IDs to be included in the bulk migration.
Each database has a maximum number of parameters allowed in an update operation. This affects how many process instance IDs you can include in a bulk migration request. Below are the limits for each supported database:
-
H2 → 50,000 IDs
-
PostgreSQL → 50,000 IDs
-
Oracle → 1,000 IDs
-
MS SQL Server → 2,000 IDs
-
Db2 → 32,000 IDs
-
For example:
{
"planId": "<plan_id>",
"processInstanceIds": ["id1", "id2", "id3", ...]
}
Which returns the following:
{
"status": 200,
"message": "Migration finished",
"data": {
"migrationId": "<migration_id>",
"planId": "<plan_id>",
"migratedProcessInstancesCount": 100000
}
}
Where:
- migrationId
-
is the unique identifier for the migration.
- migratedProcessInstancesCount
-
is the number of instances migrated.
- skippedProcessInstanceIds
-
lists any IDs that were not migrated, if they exist.
You can use GET /pim/migration/processes/{processInstanceId} to return the list of migrations associated with a given Process Instance, including timestamps for when the migration was created and applied.
{
"status": 200,
"message": "Retrieved migrated process instance",
"data": [
{
"migrationId": "<migration_id>",
"processInstanceId": "<process_instance_id>",
"planId": "<plan_id>",
"createdAt": "2025-11-20T00:00:00.000+00:00",
"appliedAt": "2025-11-20T15:23:58.910+00:00"
} ]
}