5 Replies Latest reply on Oct 3, 2012 8:02 PM by Marcio Dantas

    Tasks Assigned to Groups Not Found

    James Williams Newbie

      Hi,

       

      I'm using JBPM 5.1 Final and have spent a couple of hours learning how tasks are returned from the TaskService. I believe I have found a bug in the way tasks are returned when they are not assigned to a particular user.

       

      I have 2 simple processes that I'm using to test my code. I'm making sure I can create a process and then return the first tasks from them.

       

      The first one SimpleHumanTaskProcess has a single task with the owner id set to "testUser". When I create the process I can use the TaskClient.getTasksOwned method to return the created tasks as expected. When I look in the database the tasks are there and have owner and creator set to "testUser".

       

      The second process is called SimpleGroupTaskProcess and has a single Human Task that has groupId = "testGroup". The process is created properly and I am able to examine the database and noticed that the task owner and creator are not set. The potential owner DOES include the "testGroup" so I would expect it to be found. Howevewr it is not retrieved when using the TaskClient.getTasksAssignedAsPotentialOwner passing in the user "testUser" and group "testGroup".

       

      After some digging I think I have found the problem. The key is that the creator and owner is not set on the task. I found the underlying named query called "TasksAssignedAsPotentialOwnerWithGroups" in the orm.xml file. The query was not taking into account the null creator and owner so was only returning the tasks belonging to the "testUser" but not the group assignment.

       

      Old
      New

      select

           new org.jbpm.task.query.TaskSummary(

           t.id,

           t.taskData.processInstanceId,

           name.text,

           subject.text,

           description.text,

           t.taskData.status,

           t.priority,

           t.taskData.skipable,

           t.taskData.actualOwner,

           t.taskData.createdBy,

           t.taskData.createdOn,

           t.taskData.activationTime,

           t.taskData.expirationTime)

      from

          Task t

          left join t.taskData.createdBy

          left join t.taskData.actualOwner

          left join t.subjects as subject

          left join t.descriptions as description

          left join t.names as name,

          OrganizationalEntity potentialOwners

      where

          ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and

          potentialOwners in elements ( t.peopleAssignments.potentialOwners )  and

          (

          name.language = :language

          or t.names.size = 0

          ) and

          (

          subject.language = :language

          or t.subjects.size = 0

          ) and

          (

          description.language = :language

          or t.descriptions.size = 0

          ) and

          t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended') and

          t.taskData.expirationTime is nul

      select

           new org.jbpm.task.query.TaskSummary(

           t.id,

           t.taskData.processInstanceId,

           name.text,

           subject.text,

           description.text,

           t.taskData.status,

           t.priority,

           t.taskData.skipable,

           owner,

           creator,

           t.taskData.createdOn,

           t.taskData.activationTime,

           t.taskData.expirationTime)

      from

          Task t

          left join t.taskData.createdBy as creator

          left join t.taskData.actualOwner as owner

          left join t.subjects as subject

          left join t.descriptions as description

          left join t.names as name,

          OrganizationalEntity potentialOwners

      where

          ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and

          potentialOwners in elements ( t.peopleAssignments.potentialOwners )  and

          (

          name.language = :language

          or t.names.size = 0

          ) and

          (

          subject.language = :language

          or t.subjects.size = 0

          ) and

          (

          description.language = :language

          or t.descriptions.size = 0

          ) and

          t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended') and

          t.taskData.expirationTime is null

      This appears to work.

       

      I do have a couple of questions though. Should tasks be created in the database without having at least a creator id? Is this expected behaviour for tasks assigned to groups?

       

      I have attached my processes, just in case there is something I've done wrong that someone can help me with.

       

      Thanks

       

      James

        • 2. Re: Tasks Assigned to Groups Not Found
          Alessandro Dionisi Newbie

          Hi James,

          did you find a solution to this?

          • 3. Re: Tasks Assigned to Groups Not Found
            James Williams Newbie

            Hi Alessandro,

             

            Not really. The question has been marked as assumed answered but hasn't actually been answered. The new query above does work but the question of why tasks can be created without a creator has not been resolved.

             

            The jira I created has been assigned to Kris V. so I'd be tempted to ask him when this is planned to be fixed.

             

            Cheers

             

            James

            • 4. Re: Tasks Assigned to Groups Not Found
              Alessandro Dionisi Newbie

              Hi James,

               

              thank you for the rapid answer. I've tried your solution and it works. The strange thing I found is that the query "TasksAssignedAsPotentialOwnerWithGroups" in the file Taskorm.xml in library jbpm-human-task-core-5.3.0-final.jar seems to be interpreted differently, on different Hibernate versions I think (3.6.10.Final vs. 3.2.2 GA). I noted this comparing the examples JBPM provides in the installer; if I start the human-task-server using the ant task (that references Hibernate 3.2.2.GA in the classpath) the query TasksAssignedAsPotentialOwnerWithGroups works and generates the following SQL (that works):

               

              SELECT task0_.ID AS col_0_0_, task0_.processinstanceid AS col_1_0_,

                     names5_.text AS col_2_0_, subjects3_.text AS col_3_0_,

                     descriptio4_.text AS col_4_0_, task0_.status AS col_5_0_,

                     task0_.priority AS col_6_0_, task0_.skipable AS col_7_0_,

                     task0_.actualowner_id AS col_8_0_, task0_.createdby_id AS col_9_0_,

                     task0_.createdon AS col_10_0_, task0_.activationtime AS col_11_0_,

                     task0_.expirationtime AS col_12_0_, task0_.processid AS col_13_0_,

                     task0_.processsessionid AS col_14_0_

                FROM task task0_ LEFT OUTER JOIN organizationalentity user1_

                     ON task0_.createdby_id = user1_.ID

                     LEFT OUTER JOIN organizationalentity user2_

                     ON task0_.actualowner_id = user2_.ID

                     LEFT OUTER JOIN i18ntext subjects3_

                     ON task0_.ID = subjects3_.task_subjects_id

                     LEFT OUTER JOIN i18ntext descriptio4_

                     ON task0_.ID = descriptio4_.task_descriptions_id

                     LEFT OUTER JOIN i18ntext names5_ ON task0_.ID = names5_.task_names_id

                     ,

                     organizationalentity organizati6_

              WHERE task0_.archived = 0

                 AND (   organizati6_.ID = 'sales-rep'

                      OR organizati6_.ID IN

                                      ('sales', 'Crusaders', 'HR', 'Knights Templer', 'PM')

                     )

                 AND (organizati6_.ID IN (SELECT potentialo9_.entity_id

                                            FROM peopleassignments_potowners potentialo9_

                                           WHERE task0_.ID = potentialo9_.task_id))

                 AND (   names5_.LANGUAGE = 'en-UK'

                      OR (SELECT COUNT (names10_.task_names_id)

                            FROM i18ntext names10_

                           WHERE task0_.ID = names10_.task_names_id) = 0

                     )

                 AND (   subjects3_.LANGUAGE = 'en-UK'

                      OR (SELECT COUNT (subjects11_.task_subjects_id)

                            FROM i18ntext subjects11_

                           WHERE task0_.ID = subjects11_.task_subjects_id) = 0

                     )

                 AND (   descriptio4_.LANGUAGE = 'en-UK'

                      OR (SELECT COUNT (descriptio12_.task_descriptions_id)

                            FROM i18ntext descriptio12_

                           WHERE task0_.ID = descriptio12_.task_descriptions_id) = 0

                     )

                 AND (task0_.status IN

                                ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')

                     )

                 AND (task0_.expirationtime IS NULL);

               

              Viceversa, if I start the human-task-server in my own application that references Hibernate 3.6.10.Final the query generated is (it doesn't work):

               

              /* Formatted on 2012/08/28 12:19 (Formatter Plus v4.8.8) */

              SELECT task0_.ID AS col_0_0_, task0_.processinstanceid AS col_1_0_,

                     names5_.text AS col_2_0_, subjects3_.text AS col_3_0_,

                     descriptio4_.text AS col_4_0_, task0_.status AS col_5_0_,

                     task0_.priority AS col_6_0_, task0_.skipable AS col_7_0_,

                     task0_.actualowner_id AS col_8_0_, task0_.createdby_id AS col_9_0_,

                     task0_.createdon AS col_10_0_, task0_.activationtime AS col_11_0_,

                     task0_.expirationtime AS col_12_0_, task0_.processid AS col_13_0_,

                     task0_.processsessionid AS col_14_0_

                FROM task task0_ LEFT OUTER JOIN organizationalentity user1_

                     ON task0_.createdby_id = user1_.ID

                     LEFT OUTER JOIN organizationalentity user2_

                     ON task0_.actualowner_id = user2_.ID

                     LEFT OUTER JOIN i18ntext subjects3_

                     ON task0_.ID = subjects3_.task_subjects_id

                     LEFT OUTER JOIN i18ntext descriptio4_

                     ON task0_.ID = descriptio4_.task_descriptions_id

                     LEFT OUTER JOIN i18ntext names5_ ON task0_.ID = names5_.task_names_id

                     INNER JOIN organizationalentity user7_

                     ON task0_.actualowner_id = user7_.ID

                     INNER JOIN organizationalentity user8_ ON task0_.createdby_id = user8_.ID

                     CROSS JOIN organizationalentity organizati6_

              WHERE task0_.archived = 0

                 AND (   organizati6_.ID = 'cecchi'

                      OR organizati6_.ID IN

                                      ('sales', 'Crusaders', 'HR', 'Knights Templer', 'PM')

                     )

                 AND (organizati6_.ID IN (SELECT potentialo9_.entity_id

                                            FROM peopleassignments_potowners potentialo9_

                                           WHERE task0_.ID = potentialo9_.task_id))

                 AND (   names5_.LANGUAGE = 'en-UK'

                      OR (SELECT COUNT (names10_.task_names_id)

                            FROM i18ntext names10_

                           WHERE task0_.ID = names10_.task_names_id) = 0

                     )

                 AND (   subjects3_.LANGUAGE = 'en-UK'

                      OR (SELECT COUNT (subjects11_.task_subjects_id)

                            FROM i18ntext subjects11_

                           WHERE task0_.ID = subjects11_.task_subjects_id) = 0

                     )

                 AND (   descriptio4_.LANGUAGE = 'en-UK'

                      OR (SELECT COUNT (descriptio12_.task_descriptions_id)

                            FROM i18ntext descriptio12_

                           WHERE task0_.ID = descriptio12_.task_descriptions_id) = 0

                     )

                 AND (task0_.status IN

                                ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')

                     )

                 AND (task0_.expirationtime IS NULL);

               

              What do you think about it?

              • 5. Re: Tasks Assigned to Groups Not Found
                Marcio Dantas Newbie

                Guys,

                 

                in the "New' query above there's a cartesian product that brought me incorrect results.

                 

                Below, I change the query to use a left join.

                 

                 

                 

                select

                     new org.jbpm.task.query.TaskSummary(

                     t.id,

                     t.taskData.processInstanceId,

                     name.text,

                     subject.text,

                     description.text,

                     t.taskData.status,

                     t.priority,

                     t.taskData.skipable,

                     owner,

                     creator,

                     t.taskData.createdOn,

                     t.taskData.activationTime,

                     t.taskData.expirationTime)

                from

                    Task t

                    left join t.taskData.createdBy as creator

                    left join t.taskData.actualOwner as owner

                    left join t.subjects as subject

                    left join t.descriptions as description

                    left join t.names as name

                    left join t.peopleAssignments.potentialOwners potentialOwners

                where

                    ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and

                    (

                    name.language = :language

                    or t.names.size = 0

                    ) and

                    (

                    subject.language = :language

                    or t.subjects.size = 0

                    ) and

                    (

                    description.language = :language

                    or t.descriptions.size = 0

                    ) and

                    t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended') and

                    t.taskData.expirationTime is null