AnsweredAssumed Answered

V 5.16 - Cancel parallel task with candidate causes referential integrity violation on constraint 'AKT_FK_TSKASS_TASK'

Question asked by dsc_ on Jul 25, 2014
Latest reply on Jul 25, 2014 by dsc_
Hello,

we have modeled the following workflow:
A user requests a vacation. After that an approver can approve this request or the requestor can revoke it. This is the relevant part of our BPMN:


<?xml version="1.0" encoding="UTF-8" ?>
<definitions id="definitions" targetNamespace="http://activiti.org/bpmn20" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:cell="http://khaos.eu/cell">

   <process id="test" name="test">

      <startEvent id="start"></startEvent>
      
      <userTask id="Request" activiti:assignee="${requestor}">
      </userTask>
      
      <transaction id="innerTransaction">
         <startEvent id="innerStart"></startEvent>
         
         <parallelGateway id="split"></parallelGateway>
         <userTask id="Revoke" activiti:assignee="${requestor}">
         </userTask>
   
         
         <userTask id="Approve" activiti:candidateGroups="${approverRole}">
         </userTask>
         
           <exclusiveGateway id="join"></exclusiveGateway>
         
         <endEvent id="innerEnd">
            <cancelEventDefinition />
         </endEvent>
         
         <sequenceFlow sourceRef="innerStart" targetRef="split"></sequenceFlow>
      
         <sequenceFlow sourceRef="split" targetRef="Task"></sequenceFlow>
         <sequenceFlow sourceRef="split" targetRef="RevokeTask"></sequenceFlow>
         <sequenceFlow sourceRef="RevokeTask" targetRef="join"></sequenceFlow>
         <sequenceFlow sourceRef="Task" targetRef="join"></sequenceFlow>
         <sequenceFlow sourceRef="join" targetRef="innerEnd"></sequenceFlow>
      
      </transaction>
      
      <boundaryEvent id="transactionCancelled" attachedToRef="innerTransaction">
         <cancelEventDefinition />
      </boundaryEvent>
      
       
      <endEvent id="end"></endEvent>
      
      
      <sequenceFlow sourceRef="start" targetRef="StartTask"></sequenceFlow>
      <sequenceFlow sourceRef="StartTask" targetRef="innerTransaction"></sequenceFlow>
      
      
      <sequenceFlow sourceRef="innerTransaction" targetRef="end"></sequenceFlow>
      <sequenceFlow sourceRef="transactionCancelled" targetRef="end"></sequenceFlow>

   </process>
</definitions>


This worked fine until we updated to activiti 5.16.

The following test throws an SQLException, telling us that the foreign key "ACT_FK_TSKASS_TASK" is violated.

Test:

@Test
public void revoke() {
   // start instance with variables ["requestor" = "req", "approverRole" = "approver"]
   testEngine.start("requestor", "req", "approverRole", "approver");
   testEngine.getAssert().countTasks(1);
   Task startTask = testEngine.getEngine().getTaskService().createTaskQuery().taskDefinitionKey("Start")
         .singleResult();

   testEngine.getEngine().getTaskService().complete(startTask.getId());
   testEngine.getAssert().countTasks(2);

   Task revokeTask = testEngine.getEngine().getTaskService().createTaskQuery().taskDefinitionKey("Revoke")
         .singleResult();
   testEngine.getEngine().getTaskService().complete(revokeTask.getId());

   testEngine.getAssert().countTasks(0);
}


Exception:



10:30:18.590 [main] DEBUG o.a.e.i.interceptor.CommandContext - Error while closing command context
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database.  Cause: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "ACT_FK_TSKASS_TASK: PUBLIC.ACT_RU_IDENTITYLINK FOREIGN KEY(TASK_ID_) REFERENCES PUBLIC.ACT_RU_TASK(ID_) ('18')"; SQL statement:
delete from ACT_RU_TASK where
     
        ID_ = ?
      or 
        ID_ = ? [23503-173]
### The error may involve org.activiti.engine.impl.persistence.entity.TaskEntity.bulkDeleteTask-Inline
### The error occurred while setting parameters
### SQL: delete from ACT_RU_TASK where                 ID_ = ?       or           ID_ = ?
### Cause: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "ACT_FK_TSKASS_TASK: PUBLIC.ACT_RU_IDENTITYLINK FOREIGN KEY(TASK_ID_) REFERENCES PUBLIC.ACT_RU_TASK(ID_) ('18')"; SQL statement:
delete from ACT_RU_TASK where
     
        ID_ = ?
      or 
        ID_ = ? [23503-173]
   at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:150) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:161) ~[mybatis-3.2.5.jar:3.2.5]
   at org.activiti.engine.impl.db.DbSqlSession$BulkCheckedDeleteOperation.execute(DbSqlSession.java:340) ~[activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.db.DbSqlSession.flushRegularDeletes(DbSqlSession.java:824) ~[activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.db.DbSqlSession.flushDeletes(DbSqlSession.java:788) ~[activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:588) ~[activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:211) ~[activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:137) ~[activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66) [activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:37) [activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40) [activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35) [activiti-engine-5.16.jar:5.16]
   at org.activiti.engine.impl.TaskServiceImpl.complete(TaskServiceImpl.java:166) [activiti-engine-5.16.jar:5.16]
   at de.astrumit.pls.process.RevokeSingleTask.RevokeSingleTaskTest.revoke(RevokeSingleTaskTest.java:42) [test-classes/:na]
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_11]
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_11]
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_11]
   at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_11]
   at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
   at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
   at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
   at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
   at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
   at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) [junit-4.11.jar:na]
   at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
   at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.11.jar:na]
   at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) [junit-4.11.jar:na]
   at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) [.cp/:na]
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "ACT_FK_TSKASS_TASK: PUBLIC.ACT_RU_IDENTITYLINK FOREIGN KEY(TASK_ID_) REFERENCES PUBLIC.ACT_RU_TASK(ID_) ('18')"; SQL statement:
delete from ACT_RU_TASK where
     
        ID_ = ?
      or 
        ID_ = ? [23503-173]
   at org.h2.message.DbException.getJdbcSQLException(DbException.java:331) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.message.DbException.get(DbException.java:171) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.message.DbException.get(DbException.java:148) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:421) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:438) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:314) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.table.Table.fireConstraints(Table.java:880) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.table.Table.fireAfterRow(Table.java:897) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.command.dml.Delete.update(Delete.java:100) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.command.CommandContainer.update(CommandContainer.java:79) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.command.Command.executeUpdate(Command.java:235) ~[h2-1.3.173.jar:1.3.173]
   at org.h2.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:193) ~[h2-1.3.173.jar:1.3.173]
   at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source) ~[na:na]
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_11]
   at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_11]
   at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:55) ~[mybatis-3.2.5.jar:3.2.5]
   at com.sun.proxy.$Proxy6.execute(Unknown Source) ~[na:na]
   at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:41) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:66) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:45) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:100) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75) ~[mybatis-3.2.5.jar:3.2.5]
   at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:148) ~[mybatis-3.2.5.jar:3.2.5]
   … 39 common frames omitted



We also removed the transactional subprocess and fired an event after "Revoke" completes, which triggers a boundary-event on "Approve" with "cancelActivity=true". This led to the same error.

Thank you for looking into this issue!

Outcomes