cancel
Showing results for 
Search instead for 
Did you mean: 

Completing a Task from within a CreateListener?

ankhara33
Champ in-the-making
Champ in-the-making
I have a special situation where in some cases, when a UserTask is created, I want to 'automatically' complete it – but I still need to do some work, such as log that it was automatically created and approved. When I call getTaskService().completeTask(id) from inside the TaskListener, I get an exception about the Task not being found – it appears the TaskListener on the 'create' event is called prior to the Task actually being saved?

Is there any way to do this? I'm working with a DelegateTask inside the TaskListener.notify() method.

Thanks,
Sheila.
17 REPLIES 17

jbarrez
Star Contributor
Star Contributor
Isn't there another way to model your use case? It sounds now like you are trying to work around something which it wasn't designed for.

t5d
Champ in-the-making
Champ in-the-making
I have similar task. My process have dozens of approve tasks, that have different candidate groups.
Each candidate group normally has one user in it, and my create listener assigns this user to the task.
Now, if a user is in e.g. three different groups, and approves a document once, I want to close all other approve-tasks, that will be assigned to him automatically.
Of course there is a solution: I can use exclusive gateway before each task. But there are so many tasks, that it is not a convinient option.

So I need to close this tasks automatically. Is there some way to achieve this?

jbarrez
Star Contributor
Star Contributor
well yeah… as described above you could complete the other ones in a listener.

t5d
Champ in-the-making
Champ in-the-making
Hello, Joram. Thank you for your attention!
Have I understood you correctly: there is a way to complete a task within TaskListener?
If so, please, give me a reference or just describe, how to do it.
Thanks.

trademak
Star Contributor
Star Contributor
You can just use the TaskService in the TaskListener implementation to complete all the tasks you want to complete.

Best regards,

t5d
Champ in-the-making
Champ in-the-making
Hello, trademak. Thank you for your response.

It turned out, that I can't just use TaskService, because while in TaskListener (create/assignment) the task is not yet persisted and it can not be found by TaskService.
I did this:
<code> taskService.complete(delegateTask.getId(), variables);</code>
And it threw exception.

By the way, I have tried other variants (which did not work for me):
- signal execution by runtimeService
<code> DelegateExecution execution = delegateTask.getExecution();
runtimeService.signal(execution.getId());</code>
- listen for the transaction commit and do my work post-commit
<code>Context.getCommandContext()
  .getTransactionContext()
  .addTransactionListener(TransactionState.COMMITTED, new TransactionListener() {
    public void execute(CommandContext commandContext) {
      taskService.complete(taskId, variables);
    }
});</code>
It seemed to execute smoothly on Activiti side, but failed to commit on external transaction (Alfresco transaction), where I caught exception, that a node was changed concurrently in several transactions (other listeners do this job).

- listen for the external (Alfresco) transaction commit and do my work post-commit
I caught the same exception as previous.

Maybe it is more correct to post this question on Alfresco forums?
However, I suppose, that Alfresco-like configuration is not the unique one: other configurations also can use external transactions and face similar problems.

trademak
Star Contributor
Star Contributor
Now I don't understand your question anymore. You said that you wanted to complete "other" tasks, not the task for which you registered the task listener on. In your last post it seems like you want to complete the task for which you have defined the task listener, is that correct?
When you want the task on which you defined a task listener with create event you should be able to do this:

<blockcode>
  delegateTask.getExecution().getEngineServices().getTaskService().complete(delegateTask.getId());
</blockcode>

Doesn't that work for you?

Best regards,

t5d
Champ in-the-making
Champ in-the-making
trademak: in short: I need to close the task, that was just created and delegated to me in TaskListener.
The method you proposed does not work for me - it throws exception, that task does not exist - I have written it all above, and I suppose Ankhara33 (the author of original question) have tried the same.
By the way, I am using Activiti bundled with Alfresco 4.0.c - it is Activiti v.5.7.

frederikherema1
Star Contributor
Star Contributor
Completing the task from within a task-create/assign listener is a no go, regardless of the version of activiti you're using. The purpose of a user-task is to have a user complete it. Isn't it possible to have a gateway before that task that bypasses the task if not needed?

Or have the logic in the layer above, that is calling the API. Instead of delegating the task, you can complete() it instead, based on whatever conditions there are.