cancel
Showing results for 
Search instead for 
Did you mean: 

Associate a Comment with a UserTask at creation time?

mindcrime
Champ in-the-making
Champ in-the-making
Hi all, quick question… my client has a requirement regarding tracking history which seems to map well to the Comments
facility.  As such, I'm trying to associate a comment with a UserTask from within a TaskListener which is bound to the "create" event.  My code looks like this:

public class AddInitialCommentListener implements TaskListener
{

   @Override
   public void notify( DelegateTask task )
   {
      System.out.println( "UpdateInitialCommentListener fired!");
      
      ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
      TaskService taskService = engine.getTaskService();
      System.out.println( "taskId is: " + task.getId());
      taskService.addComment(task.getId(), null, "UserTask CREATED" );
   
      System.out.println( "added comment for task: " + task.getId());
   }
}

But, while this finds the correct taskId and throws no errors, the comment never appears in the database.  It seems to fail silently for some reason.

Should this work? If not, is there some other way to achieve the same effect?   This is Activiti 5.10, FWIW.
6 REPLIES 6

jbarrez
Star Contributor
Star Contributor
And you do see the logging being printed out?

I remember we fixed something a few months ago about calling services in listener. I don't know if that already works in Activiti 5.10.

mindcrime
Champ in-the-making
Champ in-the-making
Yes, I do see the logging get printed.  The listener fires, but nothing gets persisted to the db.

If you think there's a chance this may be related to the older version of Activiti, I can try again with the newest version.  Unfortunately the client is on 5.10 and isn't ready to upgrade, but at least we'll know then.  Thanks for the heads-up.  

jbarrez
Star Contributor
Star Contributor
Yes - I do think there might be a transaction issue which was fixed for 5.11 I believe.

mindcrime
Champ in-the-making
Champ in-the-making
OK, trying this with 5.11, I still don't get my Comment saved, but at least I get an Exception that points in the direction of what's happening.

Here's the code for the TaskListener.  Pretty straightforward:


public class SimpleTaskListener511 implements TaskListener
{

@Override
public void notify( DelegateTask task )
{
  System.out.println( "in SimpleTaskListener511" );
 
  TaskService taskService = task.getExecution().getEngineServices().getTaskService();
 
  taskService.addComment(task.getId(), null, "Initial comment added at create time" );
  System.out.println( "added comment!" );
 
}

}

And when this Listener fires, here's what happens:


INFO: Processing resource SimpleProcess511.simpleProcess.png
Made it here..
in SimpleTaskListener511
added comment!
Apr 22, 2013 12:51:33 PM org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: Cannot find task with id 305
at org.activiti.engine.impl.cmd.NeedsActiveTaskCmd.execute(NeedsActiveTaskCmd.java:51)
at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:60)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:32)
at org.activiti.engine.impl.TaskServiceImpl.addComment(TaskServiceImpl.java:259)
at org.example.activiti.SimpleTaskListener511.notify(SimpleTaskListener511.java:17)
at org.activiti.engine.impl.delegate.TaskListenerInvocation.invoke(TaskListenerInvocation.java:34)
at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
at org.activiti.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:25)
at org.activiti.engine.impl.bpmn.helper.ClassDelegate.notify(ClassDelegate.java:92)
at org.activiti.engine.impl.delegate.TaskListenerInvocation.invoke(TaskListenerInvocation.java:34)
at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
at org.activiti.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:25)
at org.activiti.engine.impl.persistence.entity.TaskEntity.fireEvent(TaskEntity.java:525)
at org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior.execute(UserTaskActivityBehavior.java:94)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:85)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:535)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:530)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerStart.java:52)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:85)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:535)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:530)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:49)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:85)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:535)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:530)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionCreateScope.execute(AtomicOperationTransitionCreateScope.java:49)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:85)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:535)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:530)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerTake.execute(AtomicOperationTransitionNotifyListenerTake.java:65)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:85)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:535)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:530)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope.execute(AtomicOperationTransitionDestroyScope.java:115)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:85)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:535)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:530)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerEnd.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerEnd.java:36)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)


mindcrime
Champ in-the-making
Champ in-the-making
OK, one more quick note on this.  It does appear to be a transaction scoping issue.  I'm guessing the taskService call is starting a new transaction, which can't read the current Task as the transaction it is created in doesn't commit until sometime after the Listener's notify() method returns.

So, if you do something like this, to allow the Listener to finish, but push creating the Comment out until a few milliseconds later, it works as expected:


public class SimpleTaskListener511 implements TaskListener
{

@Override
public void notify( DelegateTask task )
{
  System.out.println( "in SimpleTaskListener511" );
 
  TaskService taskService = task.getExecution().getEngineServices().getTaskService();
 
  Thread thread = new Thread( new CommentAdder( task, taskService));
  thread.start();
 
}

}

class CommentAdder implements Runnable
{
DelegateTask task;
TaskService taskService;

public CommentAdder( DelegateTask task, TaskService taskService )
{
  this.task = task;
  this.taskService = taskService;
}

public void run()
{
  try
  {
   Thread.sleep( 3000 );
  }
  catch( Exception e ) {}
 
  taskService.addComment(task.getId(), null, "Initial comment added at create time" );
  System.out.println( "added comment!" );
 
}
}


My question is, *should* you be able to create a Comment, using the TaskService, in the scope of the notify() method on a Listener like that?  I'm planning to try this again with 5.12 just to see if the behaviour has changed but I'd love to hear a definitive word on whether or not this is even a supported operation.

mindcrime
Champ in-the-making
Champ in-the-making
FYI, this works in 5.12, with directly calling the taskService from the Listener.  Looks like we either have to upgrade, or use the workaround above.