1 Reply Latest reply on Aug 23, 2010 4:46 PM by matrixpooh

    Cancel a process throws exceptions

    matrixpooh

      Hi,

       

      In my application, I'd like to be able to delete open (pending) process instances. My process instances usually consists of 2-8 subprocesses. The delete of the parent should be able to cascade delete its forked executions and its sub-processes, their forked children and their subprocesses. I'm running into

       

      org.hibernate.exception.ConstraintViolationException: could not delete: [org.jbpm.pvm.internal.model.ExecutionImpl#23]
          at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
          at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
          at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2559)

       

      when doing a cascade delete. Seems that the process attempts to delete the parent record immediately, without looking for children processes.

       

      Below is the complete unit test to reproduce the issue:

       

      Your input would be highly appreciated.

       

      package workflow;

      import java.util.HashMap;
      import java.util.Map;

      import junit.framework.Assert;

      import org.jbpm.api.Configuration;
      import org.jbpm.api.Execution;
      import org.jbpm.api.ExecutionService;
      import org.jbpm.api.IdentityService;
      import org.jbpm.api.ProcessEngine;
      import org.jbpm.api.ProcessInstance;
      import org.jbpm.api.RepositoryService;
      import org.jbpm.api.activity.ActivityExecution;
      import org.jbpm.api.cmd.Command;
      import org.jbpm.api.cmd.Environment;
      import org.junit.After;
      import org.junit.Before;
      import org.junit.Ignore;
      import org.junit.Test;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;

      public class OpenProcessWithinProcessTest {

          private static final Logger log = LoggerFactory.getLogger(OpenProcessWithinProcessTest.class);
         
          public IdentityService identityService ;
          public ExecutionService executionService;
          public RepositoryService repositoryService;
         
          static final String XML_MAIN = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
                  "\r\n" +
                  "<process key=\"main\" name=\"main\" xmlns=\"http://jbpm.org/4.4/jpdl\">\r\n" +
                  "   \r\n" +
                  "   <start g=\"228,13,48,48\" name=\"start\">\r\n" +
                  "      <transition g=\"-73,-9\" name=\"to-Open Case\" to=\"Open Case\"/>\r\n" +
                  "   </start>\r\n" +
                  "   \r\n" +
                  "   <foreach g=\"230,288,48,48\" in=\"#{events}\" name=\"foreach\" var=\"event\">\r\n" +
                  "      <transition to=\"Create a sub-process\"/>\r\n" +
                  "   </foreach>\r\n" +
                  "   \r\n" +
                  "   <custom class=\"com.gs.crd.requestmanager.workflow.mainprocess.OpenCase\" g=\"192,98,126,52\" name=\"Open Case\">\r\n" +
                  "      <transition g=\"-58,-12\" name=\"to-case-termination-fork\" to=\"fork1\"/>\r\n" +
                  "   </custom>\r\n" +
                  "   <join g=\"230,462,48,48\" multiplicity=\"#{quorum + 1}\" name=\"join\">\r\n" +
                  "      <transition g=\"-38,-14\" name=\"to-end\" to=\"end\"/>\r\n" +
                  "   </join>\r\n" +
                  "   <end g=\"232,628,48,48\" name=\"end\"/>\r\n" +
                  "   \r\n" +
                  "   <sub-process g=\"193,371,124,52\" name=\"Create a sub-process\" sub-process-key=\"#{event.name}\">\r\n" +
                  "      <parameter-in expr=\"#{event.id}\" subvar=\"actionlistid\"/>\r\n" +
                  "      <transition g=\"-35,-18\" name=\"to-join\" to=\"join\"/>\r\n" +
                  "   </sub-process>\r\n" +
                  "   <fork g=\"230,194,48,48\" name=\"fork1\">\r\n" +
                  "      <transition g=\"-23,-16\" name=\"to foreach\" to=\"foreach\"/>\r\n" +
                  "      <transition g=\"-67,-8\" name=\"to Wait for Case Termination\" to=\"Wait for Case Termination\"/>\r\n" +
                  "      \r\n" +
                  "   </fork>\r\n" +
                  "   <state g=\"466,358,155,52\" name=\"Wait for Case Termination\">\r\n" +
                  "      <transition g=\"-24,-2\" name=\"to join\" to=\"join\"/>\r\n" +
                  "   </state>\r\n" +
                  "     \r\n" +
                  "</process>";

          static final String XML_SUB = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
                  "\r\n" +
                  "<process description=\"Create Accounts\" key=\"subprocess\" name=\"subprocess\" xmlns=\"http://jbpm.org/4.4/jpdl\">\r\n" +
                  "    <start g=\"10,48,48,48\" name=\"start\">\r\n" +
                  "      <transition g=\"-20,-17\" name=\"to task1\" to=\"task1\"/>\r\n" +
                  "    </start>\r\n" +
                  "    \r\n" +
                  "    <end g=\"530,50,48,48\" name=\"end\"/>\r\n" +
                  "    \r\n" +
                  "    <task g=\"120,48,116,52\" name=\"task1\">\r\n" +
                  "      <assignment-handler class=\"com.gs.crd.requestmanager.workflow.DummyTaskAssignmentHandler\"/>" +
                  "      <transition g=\"-44,-18\" name=\"from-task1\" to=\"task2\"/>\r\n" +
                  "    </task>\r\n" +
                  "    \r\n" +
                  "    <task g=\"336,48,114,52\" name=\"task2\">\r\n" + 
                  "      <transition g=\"-36,-18\" name=\"from-task2\" to=\"end\"/>\r\n" +
                  "    </task>\r\n" +
                  "    \r\n" +
                  "</process>";

          String deploymentId;

         
          ProcessEngine processEngine;
          @Before
          public void setUp() throws Exception {

      //        RequestManagerServicesInitializer.initWorkflowServiceForTests();
                     
              processEngine = new Configuration().setResource("jbpm.test.cfg.xml").buildProcessEngine();

              identityService = processEngine.getIdentityService();
              executionService = processEngine.getExecutionService();
              repositoryService = processEngine.getRepositoryService();
             
              identityService.createUser("jd", "jd", "jd");
              identityService.createGroup("dummy");
              identityService.createMembership("jd", "dummy", "role");
              deploymentId = repositoryService.createDeployment().addResourceFromString("main.jpdl.xml", XML_MAIN)
                      .addResourceFromString("sub.jpdl.xml", XML_SUB).deploy();
          }

          @After public void tearDown() throws Exception {
      //        identityService.deleteUser("johndoe");
      //        identityService.deleteGroup("group");
      //        repositoryService.deleteDeploymentCascade(deploymentId);
          }

         
          @Test
          public void testCancelBusinessProcess(){
             
              SubprocessInputValues[] events = new SubprocessInputValues[] {
                      new SubprocessInputValues("subprocess", 134),
                      new SubprocessInputValues("subprocess", 134)};
             
              Map<String, Object> variables = new HashMap<String, Object>();
              variables.put("events", events);
              variables.put("quorum", new Integer(events.length));
              final ProcessInstance processInstance = executionService.startProcessInstanceByKey("main", variables);
              String processInstanceId = processInstance.getId();
              final ProcessInstance processInstance1  = executionService.createProcessInstanceQuery().processInstanceId(processInstanceId).uniqueResult();;
             
      //        ((ActivityExecution)processInstance).end(Execution.STATE_ENDED);
              processEngine.execute(new Command<Void>(){
                  @Override
                  public Void execute(Environment environment) throws Exception {
                      ((ActivityExecution)processInstance1).end(Execution.STATE_ENDED);
                      return null;
                  }});   

          }

      }

        • 1. Re: Cancel a process throws exceptions
          matrixpooh
          package workflow;
          
          import java.util.HashMap;
          import java.util.Map;
          
          import junit.framework.Assert;
          
          import org.jbpm.api.Configuration;
          import org.jbpm.api.Execution;
          import org.jbpm.api.ExecutionService;
          import org.jbpm.api.IdentityService;
          import org.jbpm.api.ProcessEngine;
          import org.jbpm.api.ProcessInstance;
          import org.jbpm.api.RepositoryService;
          import org.jbpm.api.activity.ActivityExecution;
          import org.jbpm.api.cmd.Command;
          import org.jbpm.api.cmd.Environment;
          import org.junit.After;
          import org.junit.Before;
          import org.junit.Ignore;
          import org.junit.Test;
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          
          public class OpenProcessWithinProcessTest {
          
              private static final Logger log = LoggerFactory.getLogger(OpenProcessWithinProcessTest.class);
              
              public IdentityService identityService ;
              public ExecutionService executionService;
              public RepositoryService repositoryService;
              
              static final String XML_MAIN = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + 
                      "\r\n" + 
                      "<process key=\"main\" name=\"main\" xmlns=\"http://jbpm.org/4.4/jpdl\">\r\n" + 
                      "   \r\n" + 
                      "   <start g=\"228,13,48,48\" name=\"start\">\r\n" + 
                      "      <transition g=\"-73,-9\" name=\"to-Open Case\" to=\"Open Case\"/>\r\n" + 
                      "   </start>\r\n" + 
                      "   \r\n" + 
                      "   <foreach g=\"230,288,48,48\" in=\"#{events}\" name=\"foreach\" var=\"event\">\r\n" + 
                      "      <transition to=\"Create a sub-process\"/>\r\n" + 
                      "   </foreach>\r\n" + 
                      "   \r\n" + 
                      "   <custom class=\"com.gs.crd.requestmanager.workflow.mainprocess.OpenCase\" g=\"192,98,126,52\" name=\"Open Case\">\r\n" + 
                      "      <transition g=\"-58,-12\" name=\"to-case-termination-fork\" to=\"fork1\"/>\r\n" + 
                      "   </custom>\r\n" + 
                      "   <join g=\"230,462,48,48\" multiplicity=\"#{quorum + 1}\" name=\"join\">\r\n" + 
                      "      <transition g=\"-38,-14\" name=\"to-end\" to=\"end\"/>\r\n" + 
                      "   </join>\r\n" + 
                      "   <end g=\"232,628,48,48\" name=\"end\"/>\r\n" + 
                      "   \r\n" + 
                      "   <sub-process g=\"193,371,124,52\" name=\"Create a sub-process\" sub-process-key=\"#{event.name}\">\r\n" + 
                      "      <parameter-in expr=\"#{event.id}\" subvar=\"actionlistid\"/>\r\n" + 
                      "      <transition g=\"-35,-18\" name=\"to-join\" to=\"join\"/>\r\n" + 
                      "   </sub-process>\r\n" + 
                      "   <fork g=\"230,194,48,48\" name=\"fork1\">\r\n" + 
                      "      <transition g=\"-23,-16\" name=\"to foreach\" to=\"foreach\"/>\r\n" + 
                      "      <transition g=\"-67,-8\" name=\"to Wait for Case Termination\" to=\"Wait for Case Termination\"/>\r\n" + 
                      "      \r\n" + 
                      "   </fork>\r\n" + 
                      "   <state g=\"466,358,155,52\" name=\"Wait for Case Termination\">\r\n" + 
                      "      <transition g=\"-24,-2\" name=\"to join\" to=\"join\"/>\r\n" + 
                      "   </state>\r\n" + 
                      "     \r\n" + 
                      "</process>";
          
              static final String XML_SUB = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + 
                      "\r\n" + 
                      "<process description=\"Create Accounts\" key=\"subprocess\" name=\"subprocess\" xmlns=\"http://jbpm.org/4.4/jpdl\">\r\n" + 
                      "    <start g=\"10,48,48,48\" name=\"start\">\r\n" + 
                      "      <transition g=\"-20,-17\" name=\"to task1\" to=\"task1\"/>\r\n" + 
                      "    </start>\r\n" + 
                      "    \r\n" + 
                      "    <end g=\"530,50,48,48\" name=\"end\"/>\r\n" + 
                      "    \r\n" + 
                      "    <task g=\"120,48,116,52\" name=\"task1\">\r\n" + 
                      "      <assignment-handler class=\"com.gs.crd.requestmanager.workflow.DummyTaskAssignmentHandler\"/>" +
                      "      <transition g=\"-44,-18\" name=\"from-task1\" to=\"task2\"/>\r\n" + 
                      "    </task>\r\n" + 
                      "    \r\n" + 
                      "    <task g=\"336,48,114,52\" name=\"task2\">\r\n" +  
                      "      <transition g=\"-36,-18\" name=\"from-task2\" to=\"end\"/>\r\n" + 
                      "    </task>\r\n" + 
                      "    \r\n" + 
                      "</process>";
          
              String deploymentId;
          
              
              ProcessEngine processEngine;
              @Before 
              public void setUp() throws Exception {
          
          //        RequestManagerServicesInitializer.initWorkflowServiceForTests();
                          
                  processEngine = new Configuration().setResource("jbpm.test.cfg.xml").buildProcessEngine();
          
                  identityService = processEngine.getIdentityService();
                  executionService = processEngine.getExecutionService();
                  repositoryService = processEngine.getRepositoryService();
                  
                  identityService.createUser("jd", "jd", "jd");
                  identityService.createGroup("dummy");
                  identityService.createMembership("jd", "dummy", "role");
                  deploymentId = repositoryService.createDeployment().addResourceFromString("main.jpdl.xml", XML_MAIN)
                          .addResourceFromString("sub.jpdl.xml", XML_SUB).deploy();
              }
          
              @After public void tearDown() throws Exception {
          //        identityService.deleteUser("johndoe");
          //        identityService.deleteGroup("group");
          //        repositoryService.deleteDeploymentCascade(deploymentId);
              }
          
              @Ignore 
              public void testDefault() throws Exception {
                  ProcessInstance processInstance = executionService.startProcessInstanceByKey("main");
                  Assert.assertNotNull(processInstance.getId());
              }
              
              @Test
              public void testCancelBusinessProcess(){
                  
                  SubprocessInputValues[] events = new SubprocessInputValues[] { 
                          new SubprocessInputValues("subprocess", 134),
                          new SubprocessInputValues("subprocess", 134)};
                  
                  Map<String, Object> variables = new HashMap<String, Object>();
                  variables.put("events", events);
                  variables.put("quorum", new Integer(events.length)); 
                  final ProcessInstance processInstance = executionService.startProcessInstanceByKey("main", variables);
                  String processInstanceId = processInstance.getId();
                  final ProcessInstance processInstance1  = executionService.createProcessInstanceQuery().processInstanceId(processInstanceId).uniqueResult();;
                  
          //        ((ActivityExecution)processInstance).end(Execution.STATE_ENDED);
                  processEngine.execute(new Command<Void>(){
                      @Override
                      public Void execute(Environment environment) throws Exception {
                          ((ActivityExecution)processInstance1).end(Execution.STATE_ENDED);
                          return null;
                      }});    
          
              }
          
          }