cancel
Showing results for 
Search instead for 
Did you mean: 

Task query by execution id returns null (for a single process)

felipe1
Champ in-the-making
Champ in-the-making
I'm using a class that extends <b>JavaDelegate</b> in a service task, and I need to get the current assignee from within that JavaDelegate.

So I created the following utils method that returns the current task:


   protected Task obtemTarefa(DelegateExecution execution) {
      return execution.getEngineServices().getTaskService().createTaskQuery().executionId(execution.getId()).singleResult();
   }


and I call it from my JavaDelegate where I call <b>task.getAssignee()</b>. It works great on 4 different processes. However it fails on a 5th process, because singleResult() always returns <b>null</b>.

I have debugged that code for quite a while, and, at that point, <b>execution</b> is a valid object, and it has values for <b>id</b>, <b>processDefinitionId</b>, and many others. I have queried the ACT_RU_EXECUTION and find out a valid execution with the same id…

Any clues?

Thanks.
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
Wait - i don't get why it works in those 4 cases

How come the JavaDelegate service task has a task to start with? The execution that is passed into the delegate there should not be assigned to any user task, but to the service task!

felipe1
Champ in-the-making
Champ in-the-making
My Service task (id="efetivacao") is called right after a UserTask. Ultimately, what I want to do, is get the assignee from that UserTask (id="UserTask_1").

I agree with you on that. It is a really strange behaviour, but I can reproduce it.

I have mocked the service task in my junit test:

<java>
public class ServiceTaskTestMock implements JavaDelegate {

public static AtomicInteger CALL_COUNT = new AtomicInteger();
public static Task t;

@Override
public void execute(DelegateExecution execution) throws Exception {
  t = execution.getEngineServices().getTaskService().createTaskQuery().executionId(execution.getId()).singleResult();

  CALL_COUNT.incrementAndGet();
}

}
</java>

and this is how my test looks like:

<java>
@Test
@Deployment(resources = { "sample-process.bpmn" })
@MockServiceTask(id = "efetivacao", originalClassName = "com.acme.product.workflow.efetivacao.EfetivacaoDeLancamentoDeVerba", mockedClassName = "teste.helper.ServiceTaskTestMock")
public void completeProcess() throws Exception {
  String processId = getProcessId("sample-process");

  assertNotNull("Process was published", processId);

  Map<String, Object> vars = new HashMap<>();

  startProcess(idProcesso, vars);

  Task activeTask = getActiveTask();

  completeTask(activeTask.getId(), vars);
  activeTask = getActiveTask();

  assertEquals("1 call was made to service task method", 1, ServiceTaskTestMock.CALL_COUNT.get());
  assertNotNull("Task is not null", ServiceTaskTestMock.t);
  assertEquals("There are no more active tasks", 0, activitiRule.getTaskService().createTaskQuery().list().size());
}
</java>

And my process definition is the following:

<code>
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlnsSmiley Surprisedmgdi="http://www.omg.org/spec/DD/20100524/DI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
id="Definitions_1"
name="sample-process"
targetNamespace="sample-category">
<process
  id="sample-process"
  name="Sample process"
  isExecutable="true">

  <extensionElements>
   <activiti:executionListener
    xsi:type="xsd:anyType"
    class="com.acme.workflow.activiti.impl.NotificaProcessoConcluidoListener"
    event="end">
    <activiti:field
     xsi:type="xsd:anyType"
     name="destinatarios"
     stringValue="TODOS_OS_PARTICIPANTES" />
    <activiti:field
     xsi:type="xsd:anyType"
     name="variaveisParaEmail"
     stringValue="fun,lancamentoValor,mesAno" />
   </activiti:executionListener>
  </extensionElements>

  <startEvent
   id="startevent1"
   activiti:formKey="sample-process_inicio.xhtml"
   activiti:initiator="solicitante"
   name="Inicio">
   <outgoing>SequenceFlow_9</outgoing>
  </startEvent>
  <userTask
   id="UserTask_2"
   activiti:assignee="#{solicitante}"
   activiti:formKey="sample-process_alteracao.xhtml"
   name="Altera solicitacão">
   <extensionElements>
    <activiti:taskListener
     xsi:type="xsd:anyType"
     event="create"
     expression="${preparaEmailActiviti.variaveisParaEmail(task.id, 'fun', 'lancamentoValor', 'mesAno')}" />
   </extensionElements>

   <incoming>SequenceFlow_8</incoming>
   <outgoing>SequenceFlow_10</outgoing>
  </userTask>
  <sequenceFlow
   id="SequenceFlow_9"
   sourceRef="startevent1"
   targetRef="UserTask_1" />
  <sequenceFlow
   id="SequenceFlow_10"
   sourceRef="UserTask_2"
   targetRef="UserTask_1" />
  <userTask
   id="UserTask_1"
   activiti:formKey="sample-process_aprovacao.xhtml"
   activiti:candidateGroups="rh"
   name="Aprovação do RH">
   <extensionElements>
    <activiti:taskListener
     xsi:type="xsd:anyType"
     event="create"
     expression="${preparaEmailActiviti.variaveisParaEmail(task.id, 'fun', 'lancamentoValor', 'mesAno')}" />
   </extensionElements>

   <incoming>SequenceFlow_9</incoming>
   <incoming>SequenceFlow_10</incoming>
   <outgoing>SequenceFlow_2</outgoing>
  </userTask>
  <sequenceFlow
   id="SequenceFlow_2"
   sourceRef="UserTask_1"
   targetRef="ExclusiveGateway_2" />
  <exclusiveGateway
   id="ExclusiveGateway_2"
   name="Verifica se reprovado"
   default="SequenceFlow_7">
   <incoming>SequenceFlow_2</incoming>
   <outgoing>SequenceFlow_7</outgoing>
   <outgoing>SequenceFlow_8</outgoing>
  </exclusiveGateway>
  <sequenceFlow
   id="SequenceFlow_7"
   sourceRef="ExclusiveGateway_2"
   targetRef="efetivacao" />
  <sequenceFlow
   id="SequenceFlow_8"
   name="reprovado"
   sourceRef="ExclusiveGateway_2"
   targetRef="UserTask_2">
   <conditionExpression
    xsi:type="tFormalExpression"
    id="FormalExpression_2">#{reprovado == true}</conditionExpression>
  </sequenceFlow>
  <endEvent
   id="EndEvent_1"
   name="Fim">
   <incoming>SequenceFlow_4</incoming>
  </endEvent>
  <serviceTask
   id="efetivacao"
   activiti:class="com.acme.product.workflow.efetivacao.EfetivacaoDeLancamentoDeVerba"
   name="Efetivação">
   <extensionElements>
    <activiti:taskListener
     xsi:type="xsd:anyType"
     event="complete"
     expression="${preparaEmailActiviti.variaveisParaEmail(task.id, 'fun', 'lancamentoValor', 'mesAno')}" />
   </extensionElements>
   <incoming>SequenceFlow_7</incoming>
   <outgoing>SequenceFlow_1</outgoing>
  </serviceTask>
  <sequenceFlow
   id="SequenceFlow_1"
   sourceRef="efetivacao"
   targetRef="ServiceTask_1" />
  <serviceTask
   id="ServiceTask_1"
   name="Envia email para RH"
   activiti:class="com.acme.workflow.activiti.impl.NotificaProcessoConcluidoService">
   <extensionElements>
    <activiti:field
     name="gruposDestinatarios"
     stringValue="rh-notificacao" />
    <activiti:field
     name="variaveisParaEmail"
     stringValue="fun,lancamentoValor,mesAno" />
    <activiti:field
     name="mostraHistoricoDeTarefas"
     stringValue="true" />
   </extensionElements>

   <incoming>SequenceFlow_1</incoming>
   <outgoing>SequenceFlow_4</outgoing>
  </serviceTask>
  <sequenceFlow
   id="SequenceFlow_4"
   sourceRef="ServiceTask_1"
   targetRef="EndEvent_1" />
</process>
</definitions>
</code>

trademak
Star Contributor
Star Contributor
Why are you using executionId in the query instead of processInstanceId?
Can you validate that there's a task with that specific execution id in the database?

Best regards,

felipe1
Champ in-the-making
Champ in-the-making
"I have queried the ACT_RU_EXECUTION and find out a valid execution with the same id."

I have changed the method that queries the DB. Now I'm using <b>process definition id</b> to get all tasks ordered by creation date (DESC), then I get the first result. It works perfectly.

<java>
  List<Task> tasks = execution.getEngineServices().getTaskService().createTaskQuery().processInstanceId(execution.getProcessInstanceId())
    .orderByTaskCreateTime().desc().list();

  return tasks.get(0);
</java>

Thanks Tijs and Joram. 🙂