1 2 Previous Next 23 Replies Latest reply on Jun 22, 2008 9:28 AM by Ronald van Kuijk

    TaskInstance.setActorId(String) causes set TaskInstance to b

    Robert Phair Newbie

      I'm integrating jBoss jBPM with a JSF web application using a Glassfish server.

      I'm having two issues with the setActorId method of the TaskInstance object. For one, it seems that when I use this method to set a new Actor Id for a specified task, that task is rendered as closed (i.e. the ISCANCELLED flag in the TASKINSTANCE table is set to true). Actually, all the boolean flags (canceled, suspended, open, etc.) are set to true, but I think the ISCANCELLED one is what's actually causing the tasks to fail to show up in the new task list.

      The second problem I'm experiencing is that the changes I make to the list of tasks for my users do not seem to show up in the application until I redeploy it. That is, I can see the changed ActorID in the database by quering it with an SQL tool, but until I redeploy the application, those changes are not reflected. The reassigned task still appears in the "old" user's list. I was under the impression that calling JbpmContext.save(TaskInstance); followed by JbpmContext.close(); would commit the changes to the database, which appears to be happening, but the next time I rebuild the list of tasks, JBPM continues to use the data that was pulled prior to saving the new task owner.

      The code that I am using to perform the task reassignment is duplicated below. If anyone can see any obvious reason why I might be experiencing these issues, please let me know.

      This is the task assignment code in my JBPMController class, which holds all of my directly jBPM-related code.

      public void assignTask(String taskId, String userId)
       {
       long taskInstanceId = Long.parseLong(taskId);
       TaskInstance thisTask = jbpmContext.getTaskInstance(taskInstanceId);
       thisTask.setActorId(userId);
       jbpmContext.save(thisTask);
       }
      


      That code is called from my ProcessController class, a session bean in my JSF application. Here is the calling function:
      public String assignTask() throws SQLException, ClassNotFoundException{
       try{
       controller.openJbpmContext();
       if(selectedTask != null && selectedTask != ""){
       int taskId = Integer.parseInt(selectedTask);
       controller.assignTask(selectedTask, uid);
       }
       }
       finally{
       controller.closeJbpmContext();
       }
       return("Set");
       }
      


      The openJbpmContext and closeJbpmContext methods above are part of the JBPMController class, and are there only to open and close the JbpmContext object in the Controller. I've reproduced them here:
       public void openJbpmContext()
       {
       jbpmContext = jbpmConfiguration.createJbpmContext();
       }
      
       public void closeJbpmContext()
       {
       jbpmContext.close();
       }
      


      I can't think of anything else in my code that is relevant to this problem, but if more information is required, I'll do my best to post it here. If anyone has any ideas on why I might be experiencing the problems that I am, I would greatly appreciate your help!

        • 1. Re: TaskInstance.setActorId(String) causes set TaskInstance
          Robert Phair Newbie

          I apologize, the title was supposed to read "TaskInstance.setActorId(String) causes set TaskInstance to be canceled."

          • 2. Re: TaskInstance.setActorId(String) causes set TaskInstance
            Mauricio Salatino Master

            Are you using Swimlanes in your process definition?? o groups of actors?
            How you configure your tasks?

            • 3. Re: TaskInstance.setActorId(String) causes set TaskInstance
              Robert Phair Newbie

              No swimlanes or groups, just an assigned actor ID. The idea is that when a task is created, it is assigned to a "dummy" ActorID that matches a group name in our LDAP server. When a user logs in, they see a list of tasks that are assigned to their login name on the left, and a list of tasks assigned to their group on the right. By clicking on one of these task names, the user will signal the system to change the ActorID of a "group" task from the group name to the individual user name, assigning the task to that user.

              Tasks are created automatically upon entering a task node, and AssignmentHandler objects for each task assign them an appropriate ActorId.

              • 4. Re: TaskInstance.setActorId(String) causes set TaskInstance
                Mauricio Salatino Master

                That"s sounds very good to me.. you only must check that the task ids that you are handling are the correct ones..
                I"m not sure about your implementation of setting a dummy actor and then assign it to the correct one.. for this situation you should use pooled actors for tasks.. so. you assign the task to a defined group (your LDAP group) , and then when an actor login it take it from him.

                PS: sorry for my english.. i hope it helps..

                • 5. Re: TaskInstance.setActorId(String) causes set TaskInstance
                  Robert Phair Newbie

                  Thanks for your responses so far, Salaboy.

                  The reason I elected to use a single "dummy" ActorID instead of a group of pooled actors is that this will be a long-running application, and people come and go from different departments often enough that maintaining a list of available pooled actors for each task will be difficult. For instance, if persons A, B, and C are all in the list of pooled actors for a task X, they would all see X in their list of available tasks. However, if person D joins the group before X is taken by either A, B, or C, he will not see that task as available, because he is not in the list of pooled actors available for task X. D would only be able to see available tasks that were created after he'd been added to the system. It was considered less maintenance to simply have a single user ID, such as "Accounting" or "Provisioning" to represent groups of people, and then tell JBPM to fetch all tasks with those ActorIDs as available tasks for people in those groups.

                  This much seems to be working correctly, but I am still experiencing the two problems from my first post. For one, whenever I reassign a task, it is canceled. For two, my changes are not shown in the user interface until I redeploy the application, even though those same changes are shown in the database; JBPM continues to use old data.

                  Thanks for the help so far, and if you have any other suggestions, I would greatly appreciate it!

                  • 6. Re: TaskInstance.setActorId(String) causes set TaskInstance
                    Mauricio Salatino Master

                    oops.. i think you should try to use groups of users instead the dummy user called "Accounting" or "Provisioning" this is the name of a group.. so you can do it like this:

                    <task-node name="task-node1">
                     <task>
                     <assignment expression="group(Accounting)"></assignment>
                     </task>
                    </task-node>
                    


                    This will be that you are looking for.. this will publish the task for all the people in the Accounting group.. if you insert a new one to the group it will be able to do that task..
                    No maintenance is required..
                    I hope this is what you are looking for..
                    let me know if this solve your problem..


                    • 7. Re: TaskInstance.setActorId(String) causes set TaskInstance
                      Robert Phair Newbie

                      Salaboy,

                      I appreciate your help, and I don't want to sound ungrateful, but my problem doesn't lie with my assignment groups.

                      The "dummy" user group is actually working at the database level. The problem I'm experiencing is that the application doesn't pick up these changes to the database until it is redeployed. That, and when I do change the user ID on a task, it is marked as canceled for some reason.

                      If you have any further advice, I appreciate it.

                      • 8. Re: TaskInstance.setActorId(String) causes set TaskInstance
                        Mauricio Salatino Master

                         

                        The "dummy" user group is actually working at the database level.


                        I don't really understand this.. when i mention group(Accounting) is also been read in the database.. I don't know what exactly is your configuration.. but may be you should look in your identity configuration.. I mean.. Are you using the out of the box Identity Component? where is defined User, Groups and Memberships? or Are you using your personal implementation of this?

                        can you describe your process to assign the users to the tasks in more detail? i want to help you with this..

                        • 9. Re: TaskInstance.setActorId(String) causes set TaskInstance
                          Robert Phair Newbie

                           

                          "salaboy21" wrote:

                          I don't really understand this.. when i mention group(Accounting) is also been read in the database.. I don't know what exactly is your configuration.. but may be you should look in your identity configuration.. I mean.. Are you using the out of the box Identity Component? where is defined User, Groups and Memberships? or Are you using your personal implementation of this?

                          can you describe your process to assign the users to the tasks in more detail? i want to help you with this..


                          Okay, I'll try to go into as much detail as possible. I'm using my own implementation of "Groups" and "Users", rather than making use of JBPM's Groups or Swimlanes. Hopefully we'll be on the same page after this. I'll try to describe my assignment process, as well as the problems I'm experiencing as thoroughly as I can here.

                          My ProcessInstance enters a TaskNode. That TaskNode has a Task object associated with it. Upon entering the node, a TaskInstance object is automatically created. In the Properties window on my Process Editor (the Eclipse plugin), I've set the Assignment mode to "Actor" in the dropdown with a value that corresponds with one of my groups. For example, "Accounting" or "Provisioning". When the TaskInstance is automatically assigned to this Actor Id.

                          At this point, I can look in the JBPM Database, querying the JBPM_TASKINSTANCE table and see that the ACTORID column for my newly-created task is what it should be. That is, the Actor Id for this task is "Accounting," for example.

                          Now, I open my user interface, which is a JSF application. The first thing the application does is retrieve two sets of task lists. The first list is the list of tasks for the current user. So, if, for example, my login is "Octomac," any open task with an Actor Id of "Octomac" is displayed. The second list is the list of all "available" tasks; that is, any task with an Actor Id matching the name of the group that the current user is a part of. So, let's say that my login, "Octomac," is part of the Accounting group. In that case, every open task with an Actor Id of "Accounting" will be displayed.

                          So far, so good, and the application works as it should.

                          Next, the user can click on any of the tasks in the Group list. This will bring up a screen with details on the task, along with a button which the user can click to transfer ownership of the task from the Group's Actor Id to his own. So, what should happen is that, when the user clicks on the button, the selected task's Actor Id is changed to the user's ID, and the task should no longer be displayed in the list of Group tasks, having had its ID changed.

                          This is the point where the problem emerges. The first thing that I notice is that, even after I've run the code to change the Actor ID from the group's ID to the individual's, the task continues to display in the Group list. For example, if the user "Octomac" clicks on TaskInstance number 25, the page will refresh, the lists will be rebuilt, but the task will not have moved to the user's list. It will instead still be in the Group list.

                          After I observed this for the first time, I opened an SQL query tool and checked the table data found in JBPM_TASKINSTANCE. I found that the Actor ID for the task had indeed been changed in the database, but JBPM was still displaying the old data; that is, the task was being displayed as though it still had the Group name in the ACTORID column rather than the user's name.

                          At this point, I re-deployed the web application. After that, the list of group tasks no longer displayed the newly-reassigned task (which was correct behavior), but it did not display in the User's task list. I checked the database again with my SQL query tool and found that the task had been marked as canceled. That is, the boolean columns ISCANCELLED, ISBLOCKING, ISOPEN, ISSUSPENDED, and ISSIGNALING had all been set to "true". Prior to reassigning the task, only ISOPEN was true, and the rest were false. Since the function I'm using to build the task list, JbpmContext.getTaskList(userId), only returns Open tasks, the reassigned task will not display in the user's list of tasks; JBPM thinks that it's closed.

                          I don't believe my problem lies in the way I'm handling assignment, because all I'm really doing, as far as JBPM is concerned, is creating a task, assigning it to one user, and then assigning it to a different user, which I believe JBPM should be able to handle. I'm only using the ActorId property, rather than Swimlanes or Pooled Actors, because this method is simpler and fills my needs.

                          I hope that describes my assignment process and problems in sufficient detail. Thank you for sticking with me on this. Hopefully, we can find a solution soon!

                          • 10. Re: TaskInstance.setActorId(String) causes set TaskInstance
                            Ronald van Kuijk Master

                             

                            So far, so good, and the application works as it should.


                            It looks like it is, still I'd use the 'group' name in the pooled-actors field. Not every individual user in it, but the group name as a string. If the actor-id is null, it is only in the group task list (findAllTasksByPooledActor) if you want to assign it to an individual user, set the actor, but leave the pooled actors as it was. You can then 'unassign' by making the actor-id null again.

                            I don't believe my problem lies in the way I'm handling assignment, because all I'm really doing, as far as JBPM is concerned, is creating a task, assigning it to one user, and then assigning it to a different user
                            Yes, but there might be some caching issue, e.g. something not being saved or updated in the user interface (JSF object) because restarting solves it. So try to work with the pooled actors as mentioned and see what happens.

                            I'm only using the ActorId property, rather than Swimlanes or Pooled Actors, because this method is simpler and fills my needs.

                            Hmm.. I do not agree but that might be because you assume (and now *I* am assuming) pooled actors needs to be a list of individuals. It doesn't.


                            • 11. Re: TaskInstance.setActorId(String) causes set TaskInstance
                              Mauricio Salatino Master

                              I'm agree with kukeltje..
                              I think that you should try first asign null to the ActorsID and close the transaction.. then asign it the new user in another transaction.. just to see what happens..
                              Let me know the result of this.. may be it give us a clue about what is happening...

                              • 12. Re: TaskInstance.setActorId(String) causes set TaskInstance
                                Robert Phair Newbie

                                Well, this morning, I redid my Process file to assign PooledActors to tasks instead of just Actors. I was able to get the newly-created tasks to show up fine in the Group menu, but unfortunately, I'm still experiencing the same two problems I had before: the task can be assigned, but doing so sets ISCANCELLED, ISSUSPENDED, ISOPEN, ISSIGNALLING, and ISBLOCKING all to TRUE, which causes it to not be displayed in the user's task list, and both task lists are not being updated until I redeploy the application.

                                As before, the data appears committed to the database, so I assume the transaction is working somewhat correctly, if not entirely. While those five boolean flags are being set incorrectly, the task's ACTORID column is still updated to show the current user.

                                How does JBPM/Hibernate actually decide when to query the database? That is, when I call getTaskInstances(userId), does it use cached data somewhere? I suppose it must, because the same data shows up in my UI even after I've changed it at the database level. Can I force it to hit up the database every time that method is called, perhaps as a setting in the hibernate.cfg.xml?

                                On the upshot, I was mistaken about how PooledActors work, so kudos for helping me clear that much up! If anyone has any further suggestions on my issues, I'd greatly appreciate it. Thanks in advance!

                                • 13. Re: TaskInstance.setActorId(String) causes set TaskInstance
                                  Mauricio Salatino Master

                                   

                                  How does JBPM/Hibernate actually decide when to query the database?

                                  JbpmContext flush all the data to the database when close method is called.. this is when the process reach a wait state.. when the process is running all the changes are made in "memory".. so if you want to flush some change to the database in some particular moment you need to call the close method...
                                  I hope it helps..

                                  • 14. Re: TaskInstance.setActorId(String) causes set TaskInstance
                                    Robert Phair Newbie

                                    I am currently in the process of changing my Session bean to a Request bean, which seems to help with the refreshing of the list. JBPM doesn't seem to be pulling new data from the database if the bean is a Session object. I will post more information on this on Monday, and hopefully will have found a solution by then.

                                    Thanks again for everyone's help.

                                    1 2 Previous Next