2 Replies Latest reply on Nov 16, 2009 4:32 PM by Javier Alperte

    [jBPM 4.2] MySQLIntegrityConstraintViolationException ending

    Javier Alperte Newbie

      This is the exception thrown by the engine when I try to __end__ a running instance using the EndProcessInstance command. The instance has one active task (Evaluate web order), and that task has a swimlane associated (Sales Representative).

      It seems a problem with the swimlane relationship.

      NOTE: I already have configured the dialect to "org.hibernate.dialect.MySQLInnoDBDialect".

      The exception:

      com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`bpm4_jbpm/jbpm4_task`, CONSTRAINT `FK_TASK_SWIML` FOREIGN KEY (`SWIMLANE_`) REFERENCES `jbpm4_swimlane` (`DBID_`))
      


      The process definition:

      <?xml version="1.0" encoding="UTF-8"?>
      <process description="This is a test process to test: tasks, swimlanes, reminder/notifications, timers." name="Test Websale" xmlns="http://jbpm.org/4.2/jpdl">
       <swimlane assignee="${buyer}" name="Buyer"/>
       <swimlane candidate-groups="sales" name="Sales Representative"/>
       <swimlane assignee="jim" name="Finantial Department"/>
       <swimlane assignee="luci" name="Shippment Department"/>
      
       <start form="tasks/form.create.xhtml" g="81,126,48,48" name="Create new web sale order">
       <transition g="-51,-24" name="Start web sale" to="Evaluate web order"/>
       </start>
      
       <task g="209,110,153,80" name="Evaluate web order" swimlane="Sales Representative">
       <on event="timeout">
       <timer duedate="3 days"/>
       <event-listener class="com.rudder.bpm4.processes.tests.websale.Escalate">
       <field name="swimlaneName"><string value="Sales Representative"/></field>
       <field name="roleName"><string value="manager"/></field>
       <field name="defaultUser"><string value="jim"/></field>
       </event-listener>
       </on>
       <reminder duedate="1 day" repeat="4 hours"/>
       <transition g="220,245:-67,-3" name="More info needed" to="Fix web order data"/>
       <transition g="-31,-24" name="Order ok" to="Processing Fork"/>
       </task>
      
       <task g="204,300,169,43" name="Fix web order data" swimlane="Buyer">
       <!-- notification/ --> <!-- Workaround for the notification tag, force the email sent using timer -->
       <!-- on event="start" -->
       <!-- mail template="task-notification" / -->
       <!-- event-listener class="org.jbpm.jpdl.internal.activity.MailListener"></event-listener -->
       <!-- /on -->
       <transition g="363,246:-62,-2" name="More info added" to="Evaluate web order"/>
       </task>
      
       <fork g="432,126,48,48" name="Processing Fork">
       <transition g="457,78:-83,-22" name="Process payment" to="Wait for money"/>
       <transition g="457,220:-67,4" name="Process shipping" to="Ship item"/>
       </fork>
      
       <task g="509,38,116,80" name="Wait for money" swimlane="Finantial Department">
       <!-- notification/ -->
       <transition g="-42,-24" name="Update stock" to="Update books"/>
       </task>
      
       <state g="615,180,100,80" name="Ship item">
       <transition g="862,221:-136,-23" name="Items sent" to="Processing Join"/>
       </state>
      
       <join g="839,126,48,48" name="Processing Join">
       <transition g="-39,-31" name="Close order" to="Web sale processed"/>
       </join>
      
       <end g="949,126,48,48" name="Web sale processed" state="completed"/>
      
       <state g="714,39,117,78" name="Update books">
       <transition g="862,76:-30,-26" name="Stock updated" to="Processing Join"/>
       </state>
      </process>
      


      You need to start the process with the variable "buyer". This variable will maintain the userId of the user that starts the process. It will be used by the "Buyer" swimlane (assignee="${buyer}").


        • 1. Re: [jBPM 4.2] MySQLIntegrityConstraintViolationException en
          Ronald van Kuijk Master

          if you take a look at the sticky post in this topic (also read the second post about the unittest), you'll see a description on how to post possible issues. The unit test (although not explicitly mentioned in Tom's post *is* important for us to easily try to reproduce

          • 2. Re: [jBPM 4.2] MySQLIntegrityConstraintViolationException en
            Javier Alperte Newbie

            Yep! sorry.

            I deleted some stuff from the previous process definition in order to run it without problems (some custom listeners).

            Here the process definition:

            <?xml version="1.0" encoding="UTF-8"?>
            
            <process name="Test Websale" xmlns="http://jbpm.org/4.2/jpdl">
             <swimlane assignee="${buyer}" name="Buyer"/>
             <swimlane candidate-groups="sales" name="Sales Representative"/>
             <swimlane assignee="jim" name="Finantial Department"/>
             <swimlane assignee="luci" name="Shippment Department"/>
            
             <start form="tasks/form.create.xhtml" g="81,126,48,48" name="Create new web sale order">
             <transition g="-51,-24" name="Start web sale" to="Evaluate web order"/>
             </start>
            
             <task form="tasks/form.evaluate.xhtml" g="209,110,153,80" name="Evaluate web order" swimlane="Sales Representative">
             <reminder duedate="1 day" repeat="4 hours"/>
             <transition g="220,245:-67,-3" name="More info needed" to="Fix web order data"/>
             <transition g="-31,-24" name="Order ok" to="Processing Fork"/>
             </task>
            
             <task form="tasks/form.fix.xhtml" g="204,300,169,43" name="Fix web order data" swimlane="Buyer">
             <transition g="363,246:-62,-2" name="More info added" to="Evaluate web order"/>
             </task>
            
             <fork g="432,126,48,48" name="Processing Fork">
             <transition g="457,78:-83,-22" name="Process payment" to="Wait for money"/>
             <transition g="457,220:-67,4" name="Process shipping" to="Ship item"/>
             </fork>
            
             <task form="tasks/form.money.xhtml" g="509,38,116,80" name="Wait for money" swimlane="Finantial Department">
             <transition g="-42,-24" name="Update stock" to="Update books"/>
             </task>
            
             <state g="615,180,100,80" name="Ship item">
             <transition g="862,221:-136,-23" name="Items sent" to="Processing Join"/>
             </state>
            
             <join g="839,126,48,48" name="Processing Join">
             <transition g="-39,-31" name="Close order" to="Web sale processed"/>
             </join>
            
             <end g="949,126,48,48" name="Web sale processed" state="completed"/>
            
             <state g="714,39,117,78" name="Update books">
             <transition g="862,76:-30,-26" name="Stock updated" to="Processing Join"/>
             </state>
            
            </process>
            


            And here the test case that force the error:

            public class EndProcessInstanceTest extends JbpmTestCase {
             // Process deployment id
             String deploymentId;
            
             // Identities
             String salesDept;
             String finantialDept;
             String logisticDept;
             String clients;
            
             String processInstanceId;
             String processDefinitionId;
            
             // Mail server
             Wiser wiser = new Wiser();
            
             protected void setUp() throws Exception {
             super.setUp();
            
             // create identities
             salesDept = identityService.createGroup("sales");
             finantialDept = identityService.createGroup("finantial");
             logisticDept = identityService.createGroup("logistic");
             clients = identityService.createGroup("clients");
            
             identityService.createUser("john", "John", "Doe", "john@doe");
             identityService.createMembership("john", salesDept, "manager");
            
             identityService.createUser("joe", "Joe", "Smoe", "joe@smoe");
             identityService.createMembership("joe", salesDept, "sales-repre");
            
             identityService.createUser("jim", "Jim", "Cue", "jim@cue");
             identityService.createMembership("jim", finantialDept, "employee");
            
             identityService.createUser("luci", "Luci", "Lee", "luci@lee");
             identityService.createMembership("luci", logisticDept, "employee");
            
             identityService.createUser("rex", "Rex", "Frez", "rex@frez");
             identityService.createMembership("rex", clients, "client");
            
             // deploy process
             deploymentId = repositoryService.createDeployment()
             .addResourceFromClasspath("jboss-test-websale.jpdl.xml")
             .deploy();
            
             // the tearDown of the parent class will dispose the registered deployments
             registerDeployment(deploymentId);
            
             processDefinitionId = repositoryService.createProcessDefinitionQuery().
             deploymentId(deploymentId).uniqueResult().getId();
            
             // start mail server
             wiser.setPort(2525);
             wiser.start();
             }
            
             protected void tearDown() throws Exception {
             // stop mail server
             wiser.stop();
            
             // delete identities
             identityService.deleteUser("john");
             identityService.deleteUser("joe");
             identityService.deleteUser("jim");
             identityService.deleteUser("luci");
            
             identityService.deleteUser("rex");
            
             identityService.deleteGroup(salesDept);
             identityService.deleteGroup(finantialDept);
             identityService.deleteGroup(logisticDept);
             identityService.deleteGroup(clients);
            
             super.tearDown();
             }
            
             /**
             * Start a new process instance and force the instance end
             *
             * - One task and one Job will be created at process startup
             *
             * @throws Throwable
             */
             public void testEndInstance() throws Throwable {
             // Prepare start variables and start new process instance
             startProcess();
            
             // Force the process instance end with a "cancelled" state
             executionService.endProcessInstance(processInstanceId, "cancelled");
            
             assertProcessInstanceEnded(processDefinitionId);
            
             // Looking for the jobs for the given instance
             List<Job> jobs = managementService.createJobQuery()
             .processInstanceId(processInstanceId)
             .list();
            
             // No jobs should exists
             assertEquals("Unexpected number of jobs", 0, jobs.size());
            
             // No group tasks should exists for "joe"
             List<Task> taskList = taskService.findGroupTasks("joe");
             assertEquals("Expected a single task in joe's task list", 0, taskList.size());
             }
            
             private void startProcess() throws Throwable {
             ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).uniqueResult();
            
             // Prepare process variables
             Map<String, Object> orderData = new Hashtable<String, Object>();
             orderData.put("buyer", "rex"); // Used by the "Buyer" Swimlane.
            
             // Starting a process instance with variables
             ProcessInstance instance = executionService.startProcessInstanceByKey("Test_Websale", orderData);
             processInstanceId = instance.getId();
            
             // Looking for the jobs for the given instance
             List<Job> jobs = managementService.createJobQuery()
             .processInstanceId(processInstanceId)
             .list();
            
             // One job must be started at the first activity
             assertEquals("Unexpected number of jobs", 1, jobs.size());
            
             // A group task must be created for swimlane "Sales Representatives", where joe belongs to
             // Cheking the group task for joe
             List<Task> taskList = taskService.findGroupTasks("joe");
             assertEquals("Expected a single task in joe's task list", 1, taskList.size());
             }
            }