5 Replies Latest reply on Mar 2, 2010 10:11 AM by null null

    Violation of unique constraint with two splits (JBPM-2553)

    David Loiseau Newbie

      Tow split steps with two identical transition names cause a violation of unique constraint in JBPM4_EXECUTION table.

      Process Definition:

      <?xml version="1.0" encoding="UTF-8"?>
      <process key="test" name="test" xmlns="http://jbpm.org/4.0/jpdl">
       <start g="82,38,41,27" name="start1">
       <transition g="-43,-18" name="to fork1" to="fork1"/>
       </start>
       <fork g="79,112,25,20" name="fork1">
       <transition name="to task1" to="task1" g="-44,-18"/>
       <transition name="to task2" to="task2" g="-44,-18"/>
       </fork>
       <fork g="88,263,65,27" name="fork2">
       <transition name="to task1" to="task4" g="-44,-18"/>
       <transition name="to task3" to="task3" g="-44,-18"/>
       </fork>
       <task assignee="test" name="task1" g="75,189,60,42">
       <transition name="to fork2" to="fork2" g="-43,-18"/>
       </task>
       <task name="task2" g="163,117,61,31"/>
       <task name="task3" g="189,268,59,37"/>
       <task name="task4" g="93,340,52,40"/>
      </process>
      


      Test code:

      ProcessEngine processEngine = Configuration.getProcessEngine();
      RepositoryService repositoryService = (RepositoryService) processEngine.get(RepositoryService.class);
      String deploymentId = repositoryService
      .createDeployment()
      .addResourceFromClasspath("test.jpdl.xml")
       .deploy();
      Execution execution = processEngine.getExecutionService().startProcessInstanceByKey("test");
      Task task = (Task)processEngine.getTaskService().findPersonalTasks("test").get(0);
      processEngine.getTaskService().completeTask(task.getId(),"to fork2");
      


      Exception:

      Caused by: java.sql.SQLException: Violation of unique constraint $$: duplicate value(s) for column(s) $$: SYS_CT_970 in statement [update JBPM4_EXECUTION set DBVERSION_=?, ACTIVITYNAME_=?, PROCDEFID_=?, HASVARS_=?, NAME_=?, KEY_=?, ID_=?, STATE_=?, SUSPHISTSTATE_=?, PRIORITY_=?, HISACTINST_=?, PARENT_=?, INSTANCE_=?, SUPEREXEC_=?, SUBPROCINST_=? where DBID_=? and DBVERSION_=?]
      at org.hsqldb.jdbc.Util.throwError(Unknown Source)
      at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
      at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
      ... 39 more
      



      The related jira issue was closed by Ronald but I don't understand why the process definition is indicated as invalid...?

      http://jira.jboss.org/jira/browse/JBPM-2553

        • 1. Re: Violation of unique constraint with two splits (JBPM-255
          Ronald van Kuijk Master

          fork/join pairs have to be fully nested. Task 1 is used in both fork1 and fork 2 at the same time.

          • 2. Re: Violation of unique constraint with two splits (JBPM-255
            David Loiseau Newbie

            With the following process definition the problem still occurs, I don't think the nesting is the source of the problem:

            <?xml version="1.0" encoding="UTF-8"?>
            
            <process name="test" xmlns="http://jbpm.org/4.0/jpdl">
             <start g="143,8,31,30" name="start1">
             <transition to="fork1"/>
             </start>
             <fork g="143,72,65,29" name="fork1">
             <transition g="-44,-18" name="left" to="task1"/>
             <transition g="9,-24" name="right" to="task2"/>
             </fork>
             <task assignee="test" g="73,134,66,56" name="task1">
             <transition to="join1"/>
             </task>
             <task assignee="test" g="192,135,64,55" name="task2">
             <transition to="join1"/>
             </task>
             <join g="142,201,34,36" name="join1">
             <transition to="fork2"/>
             </join>
             <fork g="138,269,57,32" name="fork2">
             <transition g="-44,-18" name="left" to="task3"/>
             <transition g="-44,-18" name="right" to="task4"/>
             </fork>
             <task g="66,329,56,51" name="task3">
             <transition to="join2"/>
             </task>
             <task g="191,332,65,43" name="task4">
             <transition to="join2"/>
             </task>
             <join g="133,385,39,35" name="join2">
             <transition to="end1"/>
             </join>
             <end g="136,455,44,56" name="end1"/>
            </process>


            Code:

            String deploymentId = repositoryService.createDeployment()
             .addResourceFromClasspath(processDefinitionFilename)
             .deploy();
            
             Execution execution = executionService.startProcessInstanceByKey("test");
            
             List<Task> tasks = processEngine.getTaskService().findPersonalTasks("test");
             for(int i = 0;i<tasks.size();i++){
             System.out.println(i);
             processEngine.getTaskService().completeTask(tasks.get(i).getId());
             }
            


            • 3. Re: Violation of unique constraint with two splits (JBPM-255
              Ronald van Kuijk Master

              ok, now the pd looks correct.

              Can you make a full unitest like described in my post in http://www.jboss.org/index.html?module=bb&op=viewtopic&t=158610

              So we can see in what step it fails, use that to (probably) fix the problem. Can you also provide debug logs for the accompanying test?

              If you chance left and right in fork2 to left2 and right2 it works?

              • 4. Re: Violation of unique constraint with two splits (JBPM-255
                David Loiseau Newbie

                Process:

                <?xml version="1.0" encoding="UTF-8"?>
                
                <process name="TwoForks" xmlns="http://jbpm.org/4.0/jpdl">
                 <start g="179,17,32,29" name="start1">
                 <transition g="-43,-18" name="to fork1" to="fork1"/>
                 </start>
                 <fork g="185,95,49,50" name="fork1">
                 <transition name="left" to="task1" g="-44,-18"/>
                 <transition name="right" to="task2" g="-44,-18"/>
                 </fork>
                 <end g="193,606,38,33" name="end1"/>
                 <task name="task1" g="90,177,73,44">
                 <transition name="to fork2" to="fork2" g="-43,-18"/>
                 </task>
                 <task name="task2" g="249,172,83,48">
                 <transition name="to join2" to="join2" g="288,425:-41,-18"/>
                 </task>
                 <task name="task3" g="21,313,88,45">
                 <transition name="to join1" to="join1" g="-41,-18"/>
                 </task>
                 <task name="task4" g="154,313,88,48">
                 <transition name="to join1" to="join1" g="-41,-18"/>
                 </task>
                 <fork name="fork2" g="108,250,37,28">
                 <transition name="left" to="task3" g="-44,-18"/>
                 <transition name="right" to="task4" g="-44,-18"/>
                 </fork>
                 <join name="join1" g="112,407,51,31">
                 <transition name="to join2" to="join2" g="-41,-18"/>
                 </join>
                 <join name="join2" g="192,511,57,44">
                 <transition name="to end1" to="end1" g="-42,-18"/>
                 </join>
                </process>


                Unit Test:

                package org.jbpm.examples.fork;
                
                import java.util.Date;
                import java.util.List;
                
                import org.jbpm.api.ProcessInstance;
                import org.jbpm.api.task.Task;
                import org.jbpm.test.JbpmTestCase;
                
                import junit.framework.TestCase;
                
                public class TwoForksTest extends JbpmTestCase {
                
                
                 String deploymentId;
                
                 protected void setUp() throws Exception {
                 super.setUp();
                
                 deploymentId = repositoryService.createDeployment()
                 .addResourceFromClasspath("org/jbpm/examples/fork/process.jpdl.xml")
                 .deploy();
                 }
                
                 protected void tearDown() throws Exception {
                 repositoryService.deleteDeploymentCascade(deploymentId);
                
                 super.tearDown();
                 }
                
                 public void testTwoForks(){
                 ProcessInstance processInstance = executionService.startProcessInstanceByKey("TwoForks");
                 List<Task> tasks = taskService.createTaskQuery().list();
                 for(Task task:tasks){
                 taskService.completeTask(task.getId());
                 }
                 Date endTime = historyService
                 .createHistoryProcessInstanceQuery()
                 .processInstanceId(processInstance.getId())
                 .uniqueResult()
                 .getEndTime();
                
                 assertNotNull(endTime);
                 }
                
                }
                


                Log:

                16:07:07,015 SEV | [BaseJbpmTestCase] TEST THROWS EXCEPTION: could not update: [org.jbpm.pvm.internal.model.ExecutionImpl#14]
                org.hibernate.exception.ConstraintViolationException: could not update: [org.jbpm.pvm.internal.model.ExecutionImpl#14]
                 at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
                 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
                 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2453)
                 at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
                 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
                 at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
                 at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
                 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
                 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
                 at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
                 at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
                 at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
                 at org.jbpm.pvm.internal.tx.HibernateSessionResource.prepare(HibernateSessionResource.java:56)
                 at org.jbpm.pvm.internal.tx.StandardTransaction.commit(StandardTransaction.java:106)
                 at org.jbpm.pvm.internal.tx.StandardTransaction.complete(StandardTransaction.java:65)
                 at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:61)
                 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
                 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
                 at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
                 at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
                 at org.jbpm.pvm.internal.svc.TaskServiceImpl.completeTask(TaskServiceImpl.java:88)
                 at org.jbpm.examples.fork.TwoForksTest.testTwoForks(TwoForksTest.java:35)
                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                 at java.lang.reflect.Method.invoke(Unknown Source)
                 at junit.framework.TestCase.runTest(TestCase.java:164)
                 at org.jbpm.test.BaseJbpmTestCase.runTest(BaseJbpmTestCase.java:80)
                 at junit.framework.TestCase.runBare(TestCase.java:130)
                 at junit.framework.TestResult$1.protect(TestResult.java:106)
                 at junit.framework.TestResult.runProtected(TestResult.java:124)
                 at junit.framework.TestResult.run(TestResult.java:109)
                 at junit.framework.TestCase.run(TestCase.java:120)
                 at junit.framework.TestSuite.runTest(TestSuite.java:230)
                 at junit.framework.TestSuite.run(TestSuite.java:225)
                 at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
                 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
                 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
                 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
                 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
                Caused by: java.sql.SQLException: Violation of unique constraint $$: duplicate value(s) for column(s) $$: SYS_CT_9890 in statement [update JBPM4_EXECUTION set DBVERSION_=?, ACTIVITYNAME_=?, PROCDEFID_=?, HASVARS_=?, NAME_=?, KEY_=?, ID_=?, STATE_=?, SUSPHISTSTATE_=?, PRIORITY_=?, HISACTINST_=?, PARENT_=?, INSTANCE_=?, SUPEREXEC_=?, SUBPROCINST_=? where DBID_=? and DBVERSION_=?]
                 at org.hsqldb.jdbc.Util.throwError(Unknown Source)
                 at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
                 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
                 ... 38 more


                Regards,
                David

                • 5. Re: Violation of unique constraint with two splits (JBPM-255
                  null null Newbie

                  Is this issue confirmed as a bug?

                   

                  I got this message with followig definition:

                   

                  <?xml version="1.0" encoding="UTF-8"?>

                  <process key="LOOP" name="Loop" xmlns="http://jbpm.org/4.0/jpdl">
                      <start g="216,13,48,48" name="startNode">
                          <transition g="-45,-18" name="to decreaseCounter" to="decreaseCounter"/>
                      </start>
                      <end g="303,630,48,48" name="endNode"/>


                      <java class="de.lbbw.jbpmtest.TestActivity" g="52,277,92,52" method="sayHello" name="sayHello">
                          <arg>
                              <object expr="#{request}"/>
                          </arg>
                          <transition g="-61,-18" name="to joinHello" to="joinHello"/>
                      </java>
                      <java class="de.lbbw.jbpmtest.TestActivity" g="201,87,92,52" method="decreaseCounter" name="decreaseCounter" var="request">
                          <arg>
                              <object expr="#{request}"/>
                          </arg>
                        <transition g="-43,-18" name="to forkHello" to="forkHello"/>
                      </java>
                      <decision g="403,290,48,48" name="repeatAgain">
                          <handler class="de.lbbw.jbpmtest.RepeatAgainHandler" />

                          <transition g="-37,-18" name="AGAIN" to="decreaseCounter"/>
                          <transition g="-58,-18" name="NOTAGAIN" to="joinHello"/>


                      </decision>
                     <fork g="237,198,48,48" name="forkHello">
                          <transition g="-45,-18" name="to sayHello" to="sayHello"/>
                        <transition g="-77,-18" name="to repeatAgain" to="repeatAgain"/>
                     </fork>
                     <join g="294,473,48,48" multiplicity="3" name="joinHello">
                        <transition g="-61,-18" name="to endNode" to="endNode"/>
                     </join>
                  </process>