3 Replies Latest reply on Feb 9, 2009 6:59 AM by dleerob

    Problems with deleting a process instance of a complex proce

    jits_1998

      Hi,

      We have a complex process with multiple sub-processes, tasks and multiple child tokens in the subprocesses.

      We found that GraphSession.deleteProcessInstance() method is unable to delete the process instance.
      It falls short on following points:
      1) It is not deleting the taskinstances, though it creates the query but it is never executed.
      2) It is not deleting the sub-process and their child tokens, which are not refered by "token.getSubProcessInstance".

      Here is an updated version of deleteProcessInstance() that works for us:

      public void deleteProcessInstance(ProcessInstance processInstance, boolean includeTasks, boolean includeJobs) {
       if (processInstance==null) throw new JbpmException("processInstance is null in JbpmSession.deleteProcessInstance()");
       try {
       // find the tokens
       Query query = session.getNamedQuery("GraphSession.findTokensForProcessInstance");
       query.setEntity("processInstance", processInstance);
       List tokens = query.list();
      
       // deleteSubProcesses
       Iterator iter = tokens.iterator();
       while (iter.hasNext()) {
       Token token = (Token) iter.next();
       deleteSubProcesses(token);
      
       }
      
       // jobs
       if (includeJobs) {
       query = session.getNamedQuery("GraphSession.deleteJobsForProcessInstance");
       query.setEntity("processInstance", processInstance);
       query.executeUpdate();
       }
      
       // tasks
       if (includeTasks) {
       query = session.getNamedQuery("GraphSession.findTaskInstanceIdsForProcessInstance");
       query.setEntity("processInstance", processInstance);
       List taskInstances = query.list();
       if(taskInstances.size()>0){
       List<Long> taskInstancesId = new ArrayList<Long>();
       for(Object ti: taskInstances)
       {
       taskInstancesId.add(((TaskInstance)ti).getId());
       }
       query = session.getNamedQuery("GraphSession.deleteTaskInstancesById");
       query.setParameterList("taskInstanceIds",taskInstancesId);
       query.executeUpdate();
       }
      
      
       }
      
       // delete the logs for all the process instance's tokens
       query = session.getNamedQuery("GraphSession.selectLogsForTokens");
       query.setParameterList("tokens", tokens);
       List logs = query.list();
       iter = logs.iterator();
       while (iter.hasNext()) {
       session.delete(iter.next());
       }
       
       iter = tokens.iterator();
       while(iter.hasNext()){
       Token token = (Token)iter.next();
       if(processInstance.getRootToken().getId()!= token.getId())
       session.delete(token);
       }
      
      
      
       // then delete the process instance
       session.delete(processInstance);
      
       } catch (Exception e) {
       e.printStackTrace();
       log.error(e);
       throw new JbpmException("couldn't delete process instance '" + processInstance.getId() + "'", e);
       }
       }
      


      The "ProcessSession.findSubprocessByToken" query is as follows:
       select pi
       from org.jbpm.graph.exe.ProcessInstance as pi
       where pi.superProcessToken = :token
      


      Hope it helps... I have not checked Jira for any such known issues, please let me know if I need to raise this ticket.

      Regards,
      Jitendra

        • 1. Re: Problems with deleting a process instance of a complex p
          keith_krueger

          Hey, thank you!

          Could you provide the fragment of hibernate query configuration needed for GraphSession.deleteTaskInstancesById ?

          I tried to use the code you provided, since we have a similar problem, but I do not have that query. Thanks.

          (Also, in my env, I had to change the java 1.5 loops to pre-1.5 ones).

          • 2. Re: Problems with deleting a process instance of a complex p
            dleerob

            Thanks Jitendra for the helpful post. In the end, I managed to get my processes (with sub process) to delete successfully. I initially had problems with your exact method, but in the end it seemed to work. Here is how I got my implementation to work.

            1) I copied the method

            deleteProcessInstance(ProcessInstance processInstance, boolean includeTasks, boolean includeJobs)
            from jbpm-jpdl-3.2.3\src\jpdl\org\jbpm\db\GraphSession.java, and put it into my own manager class, and modified as mentioned in point 3).

            2) I copied the method
            deleteSubProcesses(Token token)
            from jbpm-jpdl-3.2.3\src\jpdl\org\jbpm\db\GraphSession.java, and put it into my own manager class and modified as mentioned in point 4).

            3)
            Modified deleteProcessInstance method to look as follows:
            public void deleteProcessInstance(ProcessInstance processInstance, boolean includeTasks, boolean includeJobs) {
             log.info("Deleting process instance: " + processInstance.getProcessDefinition().getName()+" ("+processInstance.getId()+")");
             if (processInstance==null) throw new JbpmException("processInstance is null in JbpmSession.deleteProcessInstance()");
             try {
             // find the tokens
             Query query = hibernateSession.getNamedQuery("GraphSession.findTokensForProcessInstance");
             query.setEntity("processInstance", processInstance);
             List tokens = query.list();
            
             // deleteSubProcesses
             Iterator iter = tokens.iterator();
             while (iter.hasNext()) {
             Token token = (Token) iter.next();
             deleteSubProcesses(token);
             }
            
             // jobs
             if (includeJobs) {
             query = hibernateSession.getNamedQuery("GraphSession.deleteJobsForProcessInstance");
             query.setEntity("processInstance", processInstance);
             query.executeUpdate();
             }
            
             // tasks
             if (includeTasks) {
             query = hibernateSession.getNamedQuery("GraphSession.findTaskInstanceIdsForProcessInstance");
             query.setEntity("processInstance", processInstance);
             List taskInstances = query.list();
             //This is where the code differs from GraphSession.deleteProcessInstance---------
             if(taskInstances.size() > 0 ) {
             for (int x = 0; x < taskInstances.size(); x++) {
             TaskInstance ti = (TaskInstance)taskInstances.get(x);
             hibernateSession.delete(ti);
             }
             }
             //---------------------------------------------------------------------------------
             }
            
             // delete the logs for all the process instance's tokens
             query = hibernateSession.getNamedQuery("GraphSession.selectLogsForTokens");
             query.setParameterList("tokens", tokens);
             List logs = query.list();
             iter = logs.iterator();
             while (iter.hasNext()) {
             hibernateSession.delete(iter.next());
             }
            
             //This code is in addition to the code found in GraphSession.deleteProcessInstance--
             //Delete tokens
             iter = tokens.iterator();
             while(iter.hasNext()) {
             Token token = (Token)iter.next();
             if(processInstance.getRootToken().getId()!= token.getId()) {
             hibernateSession.delete(token);
             }
             }
             //------------------------------------------------------------------------------------
            
             // then delete the process instance
             hibernateSession.delete(processInstance);
            
             }
             catch (Exception e) {
             throw new JbpmException("couldn't delete process instance '" + processInstance.getId() + "'", e);
             }
            
             }
            


            4) Modified deleteSubProcesses method to look as follows:
            private void deleteSubProcesses(Token token) {
             //This is where the code different from GraphSession.deleteSubProcesses(Token)--------------------
             //Commented out the following 2 lines-----------------------------------------------------
             //Query query = hibernateSession.getNamedQuery("GraphSession.findSubProcessInstances");
             //query.setEntity("processInstance", token.getProcessInstance());
             //----------------------------------------------------------------------------------------
             //Added the following 2 lines instead-----------------------------------------------------
             Query query = hibernateSession.createQuery("select pi from org.jbpm.graph.exe.ProcessInstance as pi where pi.superProcessToken = :token");
             query.setParameter("token", token);
             //----------------------------------------------------------------------------------------
             //------------------------------------------------------------------------------------------------
             List processInstances = query.list();
            
             if (processInstances == null || processInstances.isEmpty()) {
             return;
             }
            
             Iterator iter = processInstances.iterator();
             while (iter.hasNext()) {
             ProcessInstance subProcessInstance = (ProcessInstance) iter.next();
             subProcessInstance.setSuperProcessToken(null);
             token.setSubProcessInstance(null);
             deleteProcessInstance(subProcessInstance, true, true);
             }
             if (token.getChildren()!=null) {
             iter = token.getChildren().values().iterator();
             while (iter.hasNext()) {
             Token child = (Token) iter.next();
             deleteSubProcesses(child);
             }
             }
             }
            


            When I wanted to delete a process instance, I use my modified methods instead. It seemed to work.

            Can anyone see anything wrong with doing it this way?
            Hope it helps someone else.

            • 3. Re: Problems with deleting a process instance of a complex p
              dleerob

              After upgrading to Jbpm 3.3.1, it seems the GraphSession.deleteProcessInstance method is now working for me. I no longer need to use my custom method. Don't take my word for it, as perhaps further testing is still required, but can anyone else confirm if Jbpm 3.3.x has sorted out this problem out for them?