Historic completed tasks variables by assignee and processBusinessKey

Hello community,
I need to get variables of completed tasks by assignee and processKey.
What I’ve done so far, I can get completed tasks by assignee and processKey using this code, but is there any idea to get variables.

historyService.createHistoricTaskInstanceQuery()
.processDefinitionKey(PROCESS_KEY)
.finished()
.taskAssignee(assignee)
.list();

Thank you

You have fetched historic tasks for completed instances from above query. Now next step would be collecting list of taskIds from the result set. Once taskids are collected then query for variables.

Create one container class which will have associated task and its variables.

package com.bpm.camunda.dto;

import java.util.List;

import org.camunda.bpm.engine.rest.dto.history.HistoricTaskInstanceDto;
import org.camunda.bpm.engine.rest.dto.history.HistoricVariableInstanceDto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class TaskContainer {
	private HistoricTaskInstanceDto task;
	private List<HistoricVariableInstanceDto> variables;
}

Facade Api which returns above object as array like below:

@Autowired
private HistoryService historyService;

public List<TaskContainer> getTaskListWithVariables(String processDefinitionKey, String assignee) {
	List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
			.processDefinitionKey(processDefinitionKey).finished().taskAssignee(assignee).list();

	if (CollectionUtils.isNotEmpty(historicTaskInstances)) {

		Map<String, TaskContainer> taskWithVariablesMap = new HashMap<>(historicTaskInstances.size());

		List<String> taskIds = new ArrayList<>();

		historicTaskInstances.forEach(historicTaskInstance -> {
			HistoricTaskInstanceDto historicTaskInstanceDto = HistoricTaskInstanceDto
					.fromHistoricTaskInstance(historicTaskInstance);
			taskIds.add(historicTaskInstance.getId());
			TaskContainer taskContainer = new TaskContainer();
			taskContainer.setTask(historicTaskInstanceDto);
			taskWithVariablesMap.put(historicTaskInstance.getId(), taskContainer);
		});

		List<HistoricVariableInstance> historicVariableInstances = historyService
				.createHistoricVariableInstanceQuery().processDefinitionKey(processDefinitionKey)
				.taskIdIn(StringUtils.toStringArray(taskIds)).list();
		
		Map<String, List<HistoricVariableInstanceDto>> variablesMap = new HashMap<>();
		
		historicVariableInstances.forEach(historicVariableInstance ->{
			HistoricVariableInstanceDto historicVariableInstanceDto = HistoricVariableInstanceDto.fromHistoricVariableInstance(historicVariableInstance);
			if(variablesMap.containsKey(historicVariableInstanceDto.getTaskId())) {
				List<HistoricVariableInstanceDto> existingHistoricVariableInstanceDtoList = variablesMap.get(historicVariableInstanceDto.getTaskId());
				existingHistoricVariableInstanceDtoList.add(historicVariableInstanceDto);
			}else {
				List<HistoricVariableInstanceDto> historicVariableInstanceDtoList = new ArrayList<>();
				historicVariableInstanceDtoList.add(historicVariableInstanceDto);
				variablesMap.put(historicVariableInstanceDto.getTaskId(), historicVariableInstanceDtoList);
			}
		});
		

		taskIds.forEach(taskId -> {
			taskWithVariablesMap.get(taskId).setVariables(variablesMap.get(taskId));
		});
		
		return taskWithVariablesMap.values().stream().collect(Collectors.toList());
	}

	return Collections.emptyList();
}

Note: Sometimes task instance will not have any variables. So do null check wherever required.

Thank you very much @aravindhrs for your reply,
Actually it did work like a charm, but regarding your code, all the tasks gives me :

variables : null

And this is quite joking because before posting my issue, I’ve tried to use this code to get the list of all completed tasks by assignee/processKey as you said.

historyService.createHistoricTaskInstanceQuery()
.processDefinitionKey(processDefinitionKey)
.finished()
.taskAssignee(assignee)
.list();

and to get variables from these tasks, I used this code according to the doc HistoricVariableInstanceQuery

historyService.createHistoricVariableInstanceQuery()
.processDefinitionKey(processDefinitionKey)
.taskIdIn(taskIdList)
.list();

And it gives an empty array :rofl:, which obviously correct because your code too it gives no variables !!
These variables that I’m trying to get, are setted for tasks, so my question is now :

  • Can I get these variables even their tasks are completed ?
  • Are these variables stored ?
    Thank you

Yes. History service provides api to query these variables.

yes. It stored in the table ACT_HI_VARINST

Just check the scope of the variable, whether it stored as task variables or process variables.

Also check whether the tasks filtered by assignee has variables or not.

Hello @aravindhrs ,

Just check the scope of the variable, whether it stored as task variables or process variables.

I checked the table ACT_HI_VARINST, and it gives task_ID_ : null for all my variables, but for process keys, they are defined, like PROC_INST_ID, PROC_DEF_ID, PROC_DEF_KEY… So in this case, if I understand, these variables are stored as process variables ? even I set variables using TaskService. taskService.setVariables(taskId, variables)

Also check whether the tasks filtered by assignee has variables or not.

I didn’t find variables entry at all.
Thank you