Detailed explanation of process definition, process instance, personal task, process variable, group task and gateway of Activit7

Process definition

The process definition is based on BPMN2 0 standard to describe business processes, usually using design tools to model business processes. Use the tool designer to draw the process and generate two files: XXX BPMN and XXX png

Deployment process definition

    public static void main(String[] args) {
        //Create ProcessEngine object
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //Get the RepositoryService instance
        RepositoryService repositoryService = processEngine.getRepositoryService();

		// Save the specified bpm file and picture file in the activiti database
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("loan.bpmn")
                .addClasspathResource("loan.png")
                .name("Loan application process")
                .deploy();

        //Output deployment information
        System.out.println(deployment.getName());
        System.out.println(deployment.getId());
    }

Query process definition

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //Get the ProcessDefinitionQuery object, which can be considered as a query
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        //Query all current process definitions
        // Query criteria: the key defined by the process
        List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("loan")
                // Set the sorting method and sort according to the version number defined by the process
                .orderByProcessDefinitionVersion()
                .desc().list();

        //Output process definition information
        for (ProcessDefinition processDefinition : list) {
            System.out.println("Process definition ID: " + processDefinition.getId());
            System.out.println("Process definition name:" + processDefinition.getName());
            System.out.println("Process defined Key: " + processDefinition.getKey());
            System.out.println("Version number of process definition:" + processDefinition.getVersion());
            System.out.println("Process deployment ID:" + processDefinition.getDeploymentId());
        }
    }
Process definition ID: loan:1:4
 Process definition name: loan application process
 Process defined Key: loan
 Version number of process definition: 1
 Process deployment ID:1

Delete process definition

/**
     * When a process definition has a process instance started, that is, a process has not been approved, deleting the process definition fails
     * You can use repositoryservice Deletedeployment ("1", true) to forcibly delete
     * true:Cascade deletion will first delete the unfinished process nodes, and finally delete the process definition information
     * false:Without cascading, unfinished process nodes will not be deleted, and the process definition information will be deleted directly
     *
     * @param args
     */
    public static void main(String[] args) {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        // Process deployment id
        String deploymentId = "2064";

        //Delete process definition
        repositoryService.deleteDeployment(deploymentId);
        
        //repositoryService.deleteDeployment(deploymentId, true);
    }

Process definition resource query

Get process definition resource from process definition object

	@Test
    public void getProcessResources() throws IOException {
        // Process definition id
        String processDefinitionId = "loan:1:4";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // Get repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();

        // Process definition object
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId).singleResult();

        //Get bpmn
        String resource_bpmn = processDefinition.getResourceName();
        //Get png
        String resource_png = processDefinition.getDiagramResourceName();
        // resource information 
        System.out.println("bpmn: " + resource_bpmn);
        System.out.println("png: " + resource_png);

        File file_png = new File("d:/loan.png");
        File file_bpmn = new File("d:/loan.bpmn");

        byte[] b = new byte[1024];
        int len = -1;

        // Output bpmn
        InputStream resourceAsStream = null;
        resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resource_bpmn);
        FileOutputStream fileOutputStream = new FileOutputStream(file_bpmn);

        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            fileOutputStream.write(b, 0, len);
        }

        // Output picture
        resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resource_png);
        fileOutputStream = new FileOutputStream(file_png);
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            fileOutputStream.write(b, 0, len);
        }
		
		resourceAsStream.close();
        fileOutputStream.close();
    }

Query process deployment information to obtain process definition resources

	@Test
    public void getProcessResources2() throws IOException {
        //Process deployment id
        String deploymentId = "1";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //Read resources
        List<String> resources = repositoryService.getDeploymentResourceNames(deploymentId);
        String resource_png = null;
        String resource_bpmn = null;
        //Get picture
        for (String resource_name : resources) {
            if (resource_name.indexOf(".png") >= 0) {
                resource_png = resource_name;
            } else {
                resource_bpmn = resource_name;
            }
        }

        File file_png = new File("d:/loan.png");
        File file_bpmn = new File("d:/loan.bpmn");

        byte[] b = new byte[1024];
        int len = -1;

        // Output bpmn
        InputStream resourceAsStream = null;
        resourceAsStream = repositoryService.getResourceAsStream(deploymentId, resource_bpmn);
        FileOutputStream fileOutputStream = new FileOutputStream(file_bpmn);

        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            fileOutputStream.write(b, 0, len);
        }

        // Output picture
        resourceAsStream = repositoryService.getResourceAsStream(deploymentId, resource_png);
        fileOutputStream = new FileOutputStream(file_png);
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            fileOutputStream.write(b, 0, len);
        }

		resourceAsStream.close();
        fileOutputStream.close();
    }

View process history information

Even if the process definition has been deleted, the process execution history information is still saved in the activity of activiti_ hi_* Related tables. Use the HistoryService to view the relevant history

	@Test
    public void historyQuery() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //Get HistoryService
        HistoryService historyService = processEngine.getHistoryService();
        //Gets the historicactivitinstancequery object
        HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
        //Set the id of the process instance
        historicActivityInstanceQuery.processInstanceId("2501");

        //Execute query
        List<HistoricActivityInstance> list = historicActivityInstanceQuery
                .orderByHistoricActivityInstanceStartTime().asc().list();

        for (HistoricActivityInstance instance : list) {
            System.out.println(instance.getActivityId());
            System.out.println(instance.getActivityName());
            System.out.println(instance.getProcessDefinitionId());
            System.out.println(instance.getProcessInstanceId());
            System.out.println("=============================");
        }
    }
_2
StartEvent
loan:1:4
2501
=============================
_9
 Fill in form information
loan:1:4
2501
=============================
_3
 project manager
loan:1:4
2501
=============================

Process instance

A process instance is a process initiated by a user according to the process definition

Start process instance

After the process definition is deployed in activiti, you can manage the execution of the process. The process can be executed multiple times, each execution does not affect each other, and each execution is a separate process instance

To execute a process, you first need to start the process instance

    @Test
    public void startInstance(){
        //Get ProcessEngine object
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //Get RunService object
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //Create a process instance and start the process according to the process definition key
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("loan");

        //Output information about the instance
        System.out.println("Process deployment ID" + processInstance.getDeploymentId());
        System.out.println("Process definition ID" + processInstance.getProcessDefinitionId());
        System.out.println("Process instance ID" + processInstance.getId());
        System.out.println("activity ID" + processInstance.getActivityId());
    }
Process deployment ID:null
 Process definition ID:loan:1:4
 Process instance ID:2501
 activity ID:null

Businesskey of business ID

When you start a process instance and specify a businesskey at the same time, it will be in act_ ru_ The execution process instance stores the businesskey in the execution table.

Businesskey is the business ID, which is usually the primary key of the business table. The business ID corresponds to the process instance one by one.

    @Test
    public void startInstance(){
        //Get ProcessEngine object
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //Get RunService object
        RuntimeService runtimeService = processEngine.getRuntimeService();

       // The business Key is usually the primary Key of the business table
        String businessKey="123456";

        //Create a process instance and start the process according to the process definition key
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("loan",businessKey);

        //Output information about the instance
        System.out.println("Process deployment ID: " + processInstance.getDeploymentId());
        System.out.println("Process definition ID: " + processInstance.getProcessDefinitionId());
        System.out.println("Process instance ID: " + processInstance.getId());
        System.out.println("activity ID: " + processInstance.getActivityId());
    }
Process deployment ID: null
 Process definition ID: loan:1:4
 Process instance ID: 7501
 activity ID: null

Start the process instance and operate the database table

SELECT * FROM act_ ru_ The execution # process instance execution table records the execution status of the current process instance

If there is only one branch, one process instance has only one record, and the primary key of the execution table id And process instances id identical

If multiple branches are currently running, there are multiple records in the execution table, and there are primary keys and process instances of the execution table id Different records. 

No matter how many branches there are currently, there will always be a record of the primary key and process instance of the execution table id identical

After a process instance runs, the records related to the process instance in this table are deleted

SELECT * FROM act_ru_task # task execution table, which records the currently executed tasks

Start the process instance. The process is currently executing to the first task node. A record will be inserted in this table to indicate the execution of the current task. If the task is completed, the record will be deleted.

SELECT * FROM act_ru_identitylink # task participant, which records the users or groups currently participating in the task

SELECT * FROM act_hi_procinst # process instance history table

When a process instance is started, a record will be inserted into this table, and the process instance running completion record will not be deleted.

SELECT * FROM act_hi_taskinst # task history table, recording all tasks


Start a task, not just in act_ ru_ When a record is inserted into the task table, a record will also be inserted into the historical task table, which is the main record of the task history table
The key is the task id. the record in this table will not be deleted after the task is completed.

SELECT * FROM act_hi_actinst # activity history table, recording all activities

Activities include tasks, so this table records not only tasks, but also other activities during process execution, such as start events
End event.

Query process instance

When a process is running, you can query the status of the process instance and the current running node

 @Test
    public void queryProcessInstance() {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // Get RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();

        // Process definition key
        String processDefinitionKey = "loan";

        List<ProcessInstance> list = runtimeService
                .createProcessInstanceQuery()
                .processDefinitionKey(processDefinitionKey)//
                .list();

        for (ProcessInstance processInstance : list) {
            System.out.println("Process instance id: " + processInstance.getProcessInstanceId());
            System.out.println("Process definition id: " + processInstance.getProcessDefinitionId());
            System.out.println("Execution complete:" + processInstance.isEnded());
            System.out.println("Pause:" + processInstance.isSuspended());
            System.out.println(" Current activity ID: " + processInstance.getActivityId());
            System.out.println("=============================");
        }
    }
Process instance id: 2501
 Process definition id: loan:1:4
 Execution complete: false
 Pause: false
 Current activity ID: null
 Business identification Key:  : 123456

Suspend, activate process instance

All process instances suspended

When a process is defined as suspended, it is not allowed to start a new process instance, and all process instances under the process definition will be suspended

    @Test
    public void suspendOrActivateProcessDefinition() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //Get RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //Query process defined objects
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("loan").singleResult();

        // Obtain the process definition according to the definition id
        ProcessDefinition processDefinition2 = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionId("loan:1:4").singleResult();

        //Whether the instance of the current process definition is suspended
        boolean suspended = processDefinition.isSuspended();
        String processDefinitionId = processDefinition.getId();

        if (suspended) {
            //Yes, pause, activate, and activate all process instances under the process definition
            repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
            System.out.println("Process definition:" + processDefinitionId + "activation");
        } else {
        	// If activated, suspend all process instances under the process definition
            repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
            System.out.println("Process definition:" + processDefinitionId + "Hang");
        }
    }

Single process instance suspended

The operation process instance object performs a suspended operation for a single process. If a process instance is suspended, the process will not continue to execute, and an exception will be reported when the current task of the process instance is completed

    @Test
    public void suspendOrActiveProcessInstance() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //Query process instance object
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId("2501").singleResult();

        //Whether the instance of the current process definition is suspended
        boolean suspended = processInstance.isSuspended();
        String processInstanceId = processInstance.getId();

        if (suspended) {
            //Yes, pause for activation
            runtimeService.activateProcessInstanceById(processInstanceId);
            System.out.println("technological process:" + processInstanceId + "activation");
        } else {
            //Suspend if active
            runtimeService.suspendProcessInstanceById(processInstanceId);
            System.out.println("technological process:" + processInstanceId + "Hang");
        }

Personal tasks

Person in charge of assigned tasks

Fixed allocation

During business process modeling, a fixed task leader is specified. The task only executes the task step by step. Each task will be assigned a task leader according to the configuration of bpmn

UEL expression assignment

Activiti uses UEL expressions, which are part of the java EE6 specification. UEL (Unified Expression Language) is the Unified Expression Language. Activiti supports two UEL expressions: UEL value and UEL method.

1.UEL-value

Definition method 1: the assignee variable is a process variable of activiti

Definition method 2: user is a process variable of activiti, user Assign means to get the value by calling the getter method of user

2.UEL-method
loanService is a bean in the spring container that calls the getUserId() method of the bean

3. UE method is used in combination with UE value

loanService is a bean, getUser is a method of the bean, id is an activiti process variable, and id is passed to loanService as a parameter In getUser method

4. Precautions

When using expression assignment, you must ensure that the expression is executed successfully during task execution. For example, the task uses the expression ${user.userId}. When executing the task, you must ensure that the user exists in the process variable, otherwise activiti exceptions

Expression assignment task owner example

Define tasks and assign process variables

Set process variables when starting a process instance

public static void main(String[] args) {
        //Get ProcessEngine object
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //Get RunService object
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //Define process variables
        Map<String, Object> variables = new HashMap<>();
        //Set the process variable assignee
        variables.put("assignee", "Xiaobai");
        variables.put("assignee2", "Big white");

        //Create a process instance and start the process according to the process definition key
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("loan", variables);

        //Output information about the instance
        System.out.println("Process deployment ID" + processInstance.getDeploymentId());
        System.out.println("Process definition ID" + processInstance.getProcessDefinitionId());
        System.out.println("Process instance ID" + processInstance.getId());
        System.out.println("activity ID" + processInstance.getActivityId());
    }

Listener assignment

Task listeners are custom java logic or expressions that execute when corresponding task related events occur

Use the listener allocation method to execute the notify method of the listening class according to the listening events. If the method cannot be executed normally, it will also affect the execution of the task.

Add listener

Optional Event

Create: Triggered after task creation

Assignment: Triggered after task assignment

Delete: Triggered after the task is completed

All: All events are triggered

Define a task listening class, and the class must implement org activiti. engine. delegate. Tasklistener interface

public class TaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        //Designated task leader
        delegateTask.setAssignee("Xiaobai");
    }
}

Set listener information

Query task

Query the to-do tasks of the task owner

 public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // Create TaskService
        TaskService taskService = processEngine.getTaskService();

        // Process definition key
        String processDefinitionKey = "loan";
        // Task leader
        String assignee = "Xiaobai";

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(processDefinitionKey)
                .includeProcessVariables().taskAssignee(assignee).list();

        for (Task task : list) {
            System.out.println("Process instance id: " + task.getProcessInstanceId());
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());
        }
    }
Process instance id: 2501
 task id: 5002
 Task leader: Xiaobai
 Task name: Project Manager

Query task associated businessKey query

When querying to-do tasks, business information is queried through business key Association

public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // Create TaskService
        TaskService taskService = processEngine.getTaskService();
        // Create runtimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();

        // Process definition key
        String processDefinitionKey = "loan";
        // Task leader
        String assignee = "user1";
        // Query tasks through taskService
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(processDefinitionKey)
                .includeProcessVariables().taskAssignee(assignee).list();

        for (Task task : list) {
            // Obtain the process instance id with the task object
            String processInstanceId = task.getProcessInstanceId();
            // Query the process instance object with the process instance id
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            // Get the business key and query the process form details through the business key
            String businessKey = processInstance.getBusinessKey();

            System.out.println("Process instance id: " + processInstanceId);
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());
            System.out.println("business Key: " + businessKey);
        }
    }
Process instance id: 7501
 task id: 7505
 Task leader: user1
 Task name: fill in form information
 business Key: 123456

Handle tasks

Specify the task id and call TaskService to complete the task

  public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "7505";
        String assignee = "user2";

        // Create TaskService
        TaskService taskService = processEngine.getTaskService();
        // Query whether there are tasks to be handled
        Task task = taskService.createTaskQuery().taskId(taskId)
                .taskAssignee(assignee).singleResult();

        if (task != null) {
            taskService.complete(taskId);
        }
    }

Process variables

Process variables are variables set by activiti according to management needs when managing workflow

Process variable type

String 
Integer 
Short 
Long 
Double 
Boolean 
Date 
Serializable

If the object is stored in the process variable, the serializable serialization interface must be implemented. In order to prevent new fields from being deserialized, a serialVersionUID needs to be generated

Process variable scope

By default, the scope of a process variable is a process instance, a task or an execution instance
(execution)

Among the three scopes, process instances have the largest range, which can be called global variables. Tasks and execution instances are only for one task and one execution instance. The range is not as large as process instances, which is called local variables

global Duplicate variable names are not allowed in variables. If a variable with the same name is set, the later set value will overwrite the previously set variable value

Local Since the scopes of variables do not affect each other in different tasks or different execution instances, the variable names can be the same without affecting each other

Local Variable names can also be combined with global The variable name is the same and has no effect

How to use process variables

When drawing a flowchart, process variables are used through UEL expressions

1. Set the UEL expression at the assignee. The value of the expression is the person in charge of the task, such as ${assignee}. Assignee is a process variable name. Activiti obtains the value of the UEL expression, that is, the value of the process variable assignee, and assigns the task as the person in charge of the task

2. Set the UEL expression on the connection to determine the process direction, such as: m o n e y < = 2000 and {money < = 2000} and Money < = 2000 and {money > 2000}: money is a process variable name, and the result type of uel expression is Boolean

Use Global variables to control the process

Draw flow charts and deploy process definitions


Deployment process definition

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        // Deployment process definition
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("loan.bpmn")
                .addClasspathResource("loan.png")
                .name("Loan application process")
                .deploy();
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }

Create Serializable type objects

/**
 * The Serializable interface must be implemented, or an exception will be reported when the object is stored
 */
public class Loan implements Serializable {

    private Double money;


    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }
}

Set when starting a process

Set process variables when starting a process. The scope of variables is the whole process instance. Process variables are stored in map. The key in the variable set in map for the same process instance is the same, and the latter overrides the former.

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        // Process defined key
        String key = "loan";
        Map<String, Object> map = new HashMap<>();

        // Define process variables
        Loan loan = new Loan();
        loan.setMoney(1500D);
        map.put("loan", loan);
        map.put("startUser", "Initiator");
        map.put("dept", "division manager");
        map.put("finance", "Financial cashier");

        //Start the process instance and set the value of the process variable
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, map);

        System.out.println(processInstance.getName());
        System.out.println(processInstance.getProcessDefinitionId());
    }

Inquiry process and handling

  public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        String key = "loan";
        Task task = taskService.createTaskQuery().processDefinitionKey(key)
                .taskAssignee("Initiator").singleResult();

        //task!=null, indicating that the current user has a task to handle
        if (task != null) {
            System.out.println("Process instance id: " + task.getProcessInstanceId());
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());
            taskService.complete(task.getId());
        }
    }
Process instance id: 25001
 task id: 25006
 Task leader: initiator
 Task name: fill in the process form

Since the money condition is < = 2000, the routing link goes directly to the finance to query the financial cashier task:

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        // Process definition key
        String processDefinitionKey = "loan";
        // Task leader
        String assignee = "Financial cashier";
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(processDefinitionKey)
                .includeProcessVariables().taskAssignee(assignee).singleResult();

        if (task != null) {
            System.out.println("Process instance id: " + task.getProcessInstanceId());
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());
        }
    }
Process instance id: 25001
 task id: 30006
 Task leader: financial cashier
 Task name: financial cashier

Set during task handling

Set the process variable when completing the task. The process variable can only be used by other nodes after the task is completed. Its role is
The field is the entire process instance. If the key of the set process variable already has the same name in the process instance, the later set variable replaces the previous set variable.

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        //Query whether the current user has a task
        String key = "loan";
        Task task = taskService.createTaskQuery().processDefinitionKey(key)
                .taskAssignee("Initiator").singleResult();

        //Initialization parameters
        Map<String, Object> map = new HashMap<>();
        // Define process variables
        Loan loan = new Loan();
        loan.setMoney(1500D);
        map.put("loan", loan);
        map.put("finance", "Financial cashier");

        //task!=null, the current user has a task
        if (task != null) {
            //Set the value of the process variable when the task is completed
            taskService.complete(task.getId(), map);
        }
    }

Set by current process instance

Set the global variable through the process instance id. the process instance must not be completed.

 public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //The execution id of the current process instance is usually set as the currently executed process instance
        String executionId = "2601";
        //Initialization parameters
        Map<String, Object> map = new HashMap<>();
        // Define process variables
        Loan loan = new Loan();
        loan.setMoney(2500D);
        map.put("loan", loan);

        //Set the process variable through the process instance id, the process instance id, the process variable name, and the value corresponding to the process variable name
        runtimeService.setVariable(executionId, "loan", map);

        //Set multiple values
        //runtimeService.setVariables(executionId, map)
    }

Set by current task

Task id must be the current to-do task id

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //Current to do task id
        String taskId = "2501";
        TaskService taskService = processEngine.getTaskService();

        //Initialization parameters
        Map<String, Object> map = new HashMap<>();
        // Define process variables
        Loan loan = new Loan();
        loan.setMoney(2500D);
        map.put("loan", loan);

        //Setting process variables through tasks
        taskService.setVariable(taskId, "loan", loan);
        
        //Set multiple values at once
        //taskService.setVariables(taskId, variables)
    }

Involving database tables

Setting process variables will insert records in the current execution process variable table and also in the historical process variable table.

act_ru_variable
The current process variables table records the process variables that can be used by the current running process instance, including global and local variables

Id_: Primary key

Type_: Variable type

Name_: Variable name

Execution_id_: Process instance execution id,global and local All variables are stored

Proc_inst_id_: Process instance id,global and local All variables are stored

Task_id_: Task id,local Variable storage

Bytearray_: serializable Type variable storage correspondence act_ge_bytearray Tabular id

Double_: double Type variable value

Long_: long Type variable value

Text_: text Type variable value

act_hi_varinst
The historical process variables table records all created process variables, including global and local variables

Set local process variable

Set during task handling

The local process variable is set during task processing. The currently running process instance can only be used before the end of the task, and the variable is not available after the end of the task
Method is used in the current process instance, which can be queried by querying historical tasks. Set the scope as the local variable of the task. Each task can set a variable with the same name without affecting each other.

 @Test
    public void test() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        //Task id
        String taskId = "30006";

        // Define process variables
        Map<String, Object> variables = new HashMap<String, Object>();
        Loan loan = new Loan();
        loan.setMoney(1500D);

        //Variable name: loan, variable value: loan object
        variables.put("loan", loan);
            
        // Set the local variable with the scope of this task
        taskService.setVariablesLocal(taskId, variables);
        taskService.complete(taskId);
    }

Set by current task

The task id must be the current to-do task id in act_ru_task table exists

    @Test
    public void test() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        //Task id
        String taskId = "30006";

        // Define process variables
        Map<String, Object> variables = new HashMap<String, Object>();
        Loan loan = new Loan();
        loan.setMoney(1500D);

        //Setting process variables through tasks
        taskService.setVariableLocal(taskId, "loan", loan);

        //Set multiple values at once
        //taskService.setVariablesLocal(taskId, variables)
    }

Query historical process variables

    @Test
    public void test() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();

        // Create historical task query object
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();

        // Query variables associated with a process instance
        historicTaskInstanceQuery.processInstanceId("25001");

        // Query results include local variables
        historicTaskInstanceQuery.includeTaskLocalVariables();

        List<HistoricTaskInstance> list = historicTaskInstanceQuery.list();
        for (HistoricTaskInstance historicTaskInstance : list) {
            System.out.println("task id: " + historicTaskInstance.getId());
            System.out.println("Task name:" + historicTaskInstance.getName());
            System.out.println("Task leader:" + historicTaskInstance.getAssignee());
            System.out.println("task local Variable:" + historicTaskInstance.getTaskLocalVariables());
        }
    }

Group task

Candidate users candidate

In the process definition, the task leader is fixed in the assignment of the task node. If the temporary task leader changes, the process definition needs to be modified, which has poor scalability. In this case, multiple candidates can be set for the task, and participants can be selected from the candidates to complete the task.

Set task candidates

Set candidate users in the configuration of the task node in the flowchart. Multiple candidates are separated by commas

Handling group tasks

Deploy the drawn flowchart

 Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("loan.bpmn")
                .addClasspathResource("loan.png")
                .name("Loan application process")
                .deploy();

Start process instance

            String key = "loan";
            Map<String, Object> map = new HashMap<>();
            // Define process variables
            Loan loan = new Loan();
            loan.setMoney(3500D);
            map.put("loan", loan);
            map.put("startUser", "Initiator");
            //map.put("dept", "department manager");
            map.put("finance", "Financial cashier");
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,map);

Query and handle tasks

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("loan")
                .taskAssignee("Initiator")
                .singleResult();

        if (task!=null){
            System.out.println("Process instance id: " + task.getProcessInstanceId());
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());

            taskService.complete(task.getId());
        }
    }

Candidate query group task

According to the candidate query group task, if the candidate does not pick a group task, he is only a candidate, not the executor of the task

 public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        //Process defined key
        String key = "loan";
        // Candidate user
        String candidate_users = "dept1";

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidate_users)
                .list();
      
        for (Task task : list) {
           System.out.println("Process instance id: " + task.getProcessInstanceId());
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());
            // null:dept1 is a candidate, not an executor
            System.out.println("Task executor:" + task.getAssignee());
        }
    }

Candidate pickup group task

After a candidate picks up a group task, the task becomes his own personal task, even if the user is not a candidate

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        //Process defined key
        String key = "loan";
        // Candidate user
        String candidate_users = "dept1";

        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidate_users)
                .singleResult();

        if (task != null) {
            //Parameter task ID specific candidate user
            taskService.claim(task.getId(), candidate_users);
        }
    }

Candidate query personal to-do tasks

      public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        //key candidate user defined by the process
        String key = "loan";
        String assignee = "dept1";

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assignee)
                .list();

        for (Task task : list) {
            System.out.println("Process instance id: " + task.getProcessInstanceId());
            System.out.println("task id: " + task.getId());
            System.out.println("Task leader:" + task.getAssignee());
            System.out.println("Task name:" + task.getName());
            System.out.println("Task executor:" + task.getAssignee());
        }
    }
Process instance id: 2501
 task id: 5002
 Task leader: dept1
 Task name: Department Manager
 Task executor: dept1

Candidates handle personal tasks

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        String key = "loan";
        String assignee = "dept1";

        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assignee)
                .singleResult();

        if (task != null) {
            taskService.complete(task.getId());
        }
    }

Return group task

If an individual does not want to handle the group task, he can return the group task. After returning, the user will no longer be the person in charge of the task.

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        String key = "loan";
        String assignee = "dept1";

        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assignee)
                .singleResult();
        
        if (task != null) {
            // If it is set to null, the group task will be returned, that is, the task has no person in charge
            taskService.setAssignee(task.getId(), null);
        }
    }

Task handover

    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        String key = "loan";
        String assignee = "dept1";

        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assignee)
                .singleResult();


        if (task != null) {
            String taskId = task.getId();

            // Delegate the task to other candidates
            String candidateuser = "dept2";

            // Query according to the candidate and group task id. if there is a record, it indicates that the candidate is qualified to pick the task
            Task task2 = taskService.createTaskQuery().taskId(taskId)
                    .taskCandidateUser(candidateuser).singleResult();

            if (task2 != null) {
                // Handover is possible
                // The setAssignee method can also delegate tasks to other users. The delegated user may not be a candidate
                taskService.setAssignee(taskId, candidateuser);
            }
        }
    }

Involving database tables

act_ru_task
The task execution table records the currently executed task. If the task is currently a group task, all assignee s are empty. When a task is picked, this field is the Id of the picked user

act_ru_identitylink
Task participant records the current task user or group. If candidates are set for the current task, candidate records will be inserted into the table. If there are several candidates, several candidates will be inserted.

And act_ ru_ The identity link also corresponds to a history table act_hi_identitylink, to act_ru_identitylink is the same as inserting a record
Records are also inserted into the history table

gateway

Exclusive gateway

Exclusive gateway (XOR gateway, data-based exclusive gateway) is used to realize decision-making in the process.

When the process executes to the gateway, all branches will judge whether the condition is true. If it is true, the branch will be executed.

The exclusive gateway will only select one branch that is true for execution. Even if two branch conditions are true, the exclusive gateway will only select one branch for execution. The branch with the smallest task node id value is used by default.

Branching can be implemented without an exclusive gateway, such as using process variable control

Use process variables to control the process direction. If the conditions are not met and the exclusive gateway is not used, the process ends, which is an abnormal end.

If the exclusive gateway is used to determine the direction of the branch, there must be one and only one branch passing through the exclusive gateway. If all conditions of the line out of the gateway are not met, the system throws an exception.

When all branch conditions are met, all branches are executed

When all branches meet the conditions and an exclusive gateway is introduced, there must be one and only one branch of the exclusive gateway. By default, the gateway selects the path with the lowest task node Id value for execution.

Parallel Gateway

Parallel gateway allows the process to be divided into multiple branches, or multiple branches can be gathered together. The function of parallel gateway is based on the incoming and outgoing sequential flow

If the same parallel gateway has multiple incoming and outgoing sequential flows, it has the functions of branching and aggregation at the same time. At this time, the gateway will first converge all incoming sequential streams, and then cut them into multiple parallel branches.

Branch:

For all outgoing sequential flows after parallel, create a concurrent branch for each sequential flow.

Convergence:

All incoming branches that arrive at the parallel gateway and wait here until all branches entering the sequential flow arrive, the process will pass through the aggregation gateway.

difference:

The main difference from other gateways is that parallel gateways do not resolve conditions. Even if conditions are defined in the sequential flow, they are ignored.

Purpose:

Parallel gateway is often used for countersignature tasks in business applications. Countersignature tasks are tasks jointly handled by multiple participants.


Parallel gateway execution process:

1. At the first ParallelGateway, it is divided into two parallel branches, act_ ru_ The execution table of the execution process instance records that the current process instance has two branches running, act_ru_task the current task table records two tasks to be executed

2. Parallel tasks are executed before and after. When a task is executed, act_ru_task delete the corresponding task recorded in the current task table, act_ ru_ The execution table of the execution process instance records that the execution task branch is at the convergence node of the parallel gateway

3. When all branch tasks are completed and reach the aggregation node, that is, after A and B handle the tasks, they converge at the second parallel gateway, and the parallel gateway is completed

Include gateway

The inclusion gateway has the characteristics of exclusive gateway and parallel gateway.

Conditions can be defined on the outgoing sequence flow, including the conditions that the gateway can resolve

The containing gateway can select more than one sequential flow, just like the parallel gateway

The functionality of the containing gateway is based on the incoming and outgoing sequential flows

Branch:

The conditions of all outgoing sequential streams will be resolved and the result is true The sequential flow of continues in parallel, creating a branch for each sequential flow

Convergence:

When all qualified parallel branches arrive at the containing gateway, they will enter the waiting state until each branch entering the sequential flow arrives. After aggregation, the process will continue to execute through the containing gateway.	


Contains the gateway execution process:

When executing to the first containing gateway, act_ ru_ The execution process instance execution table record contains gateway branches and qualified branches, and the current task table act_ru_task records the pending tasks of qualified branches and waits for execution in parallel

When a branch is executed and converges to the second containing gateway, act_ ru_ The execution process instance execution table records that the current task contains gateway aggregation node information

When you reach the branch of the convergence node first, you have to wait for other branches to reach the convergence. When all branches reach the convergence, including the gateway, the execution is completed. Finally, the branch and convergence start from act_ru_execution process instance execution table deletion

Keywords: Java Back-end Activiti

Added by ixalmida on Mon, 13 Dec 2021 23:39:04 +0200