-
Bug
-
Resolution: Done
-
Major
-
7.43.0.Final
-
None
-
NEW
-
NEW
-
Having a running case which at the same time contains a running sub-case (containing at least one task), if you try to cancel parent case, following exception is thrown:
org.jbpm.services.api.ProcessInstanceNotFoundException: Process instance with id 1 was not found
at org.jbpm.kie.services.impl.ProcessServiceImpl.abortProcessInstance(ProcessServiceImpl.java:224)
at org.jbpm.kie.services.impl.ProcessServiceImpl.abortProcessInstance(ProcessServiceImpl.java:206)
at org.jbpm.kie.services.impl.ProcessServiceImpl.lambda$abortProcessInstances$0(ProcessServiceImpl.java:234)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.jbpm.kie.services.impl.ProcessServiceImpl.abortProcessInstances(ProcessServiceImpl.java:232)
at org.jbpm.casemgmt.impl.command.CancelCaseCommand.execute(CancelCaseCommand.java:90)
at org.jbpm.casemgmt.impl.command.CancelCaseCommand.execute(CancelCaseCommand.java:45)
at org.drools.core.fluent.impl.PseudoClockRunner.executeBatch(PseudoClockRunner.java:102)
at org.drools.core.fluent.impl.PseudoClockRunner.executeBatches(PseudoClockRunner.java:69)
at org.drools.core.fluent.impl.PseudoClockRunner.execute(PseudoClockRunner.java:61)
at org.drools.core.fluent.impl.PseudoClockRunner.execute(PseudoClockRunner.java:39)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.drools.persistence.PersistableRunner$TransactionInterceptor.execute(PersistableRunner.java:605)
at org.drools.persistence.PersistableRunner$TransactionInterceptor.execute(PersistableRunner.java:565)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.internalExecute(OptimisticLockRetryInterceptor.java:102)
at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:83)
at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:44)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:73)
at org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:45)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.jbpm.runtime.manager.impl.error.ExecutionErrorHandlerInterceptor.internalExecute(ExecutionErrorHandlerInterceptor.java:66) at org.jbpm.runtime.manager.impl.error.ExecutionErrorHandlerInterceptor.execute(ExecutionErrorHandlerInterceptor.java:52)
at org.jbpm.runtime.manager.impl.error.ExecutionErrorHandlerInterceptor.execute(ExecutionErrorHandlerInterceptor.java:29)
at org.drools.persistence.PersistableRunner.execute(PersistableRunner.java:400)
at org.drools.persistence.PersistableRunner.execute(PersistableRunner.java:68)
at org.drools.core.runtime.InternalLocalRunner.execute(InternalLocalRunner.java:37)
at org.drools.core.runtime.InternalLocalRunner.execute(InternalLocalRunner.java:41)
at org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession.execute(CommandBasedStatefulKnowledgeSession.java:537)
at org.jbpm.kie.services.impl.ProcessServiceImpl.execute(ProcessServiceImpl.java:740)
at org.jbpm.casemgmt.impl.CaseServiceImpl.cancelCase(CaseServiceImpl.java:273) at org.jbpm.casemgmt.impl.SubCaseServiceImplTest.testStartCaseWithDynamicSubCaseAbortMainCase(SubCaseServiceImplTest.java:216)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.IllegalArgumentException: Removing a detached instance org.drools.persistence.info.WorkItemInfo#1
at org.hibernate.event.internal.DefaultDeleteEventListener.disallowDeletionOfDetached(DefaultDeleteEventListener.java:196)
at org.hibernate.event.internal.DefaultDeleteEventListener.performDetachedEntityDeletionCheck(DefaultDeleteEventListener.java:184) at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:105)
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:72)
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:1015)
at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:951)
at org.hibernate.internal.SessionImpl.remove(SessionImpl.java:3461)
at org.drools.persistence.jpa.JpaPersistenceContext.remove(JpaPersistenceContext.java:142)
at org.drools.persistence.jpa.processinstance.JPAWorkItemManager.internalAbortWorkItem(JPAWorkItemManager.java:131)
at org.jbpm.workflow.instance.node.WorkItemNodeInstance.cancel(WorkItemNodeInstance.java:382)
at org.jbpm.workflow.instance.impl.NodeInstanceImpl.cancel(NodeInstanceImpl.java:160)
at org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl.setState(WorkflowProcessInstanceImpl.java:406)
at org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl.setState(WorkflowProcessInstanceImpl.java:445)
at org.jbpm.process.instance.ProcessRuntimeImpl.abortProcessInstance(ProcessRuntimeImpl.java:551)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.abortProcessInstance(StatefulKnowledgeSessionImpl.java:567)
at org.drools.core.command.runtime.process.AbortProcessInstanceCommand.execute(AbortProcessInstanceCommand.java:55)
at org.drools.core.command.runtime.process.AbortProcessInstanceCommand.execute(AbortProcessInstanceCommand.java:30)
at org.drools.core.fluent.impl.PseudoClockRunner.executeBatch(PseudoClockRunner.java:102)
at org.drools.core.fluent.impl.PseudoClockRunner.executeBatches(PseudoClockRunner.java:69)
at org.drools.core.fluent.impl.PseudoClockRunner.execute(PseudoClockRunner.java:61)
at org.drools.core.fluent.impl.PseudoClockRunner.execute(PseudoClockRunner.java:39)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.drools.persistence.PersistableRunner$TransactionInterceptor.execute(PersistableRunner.java:605)
at org.drools.persistence.PersistableRunner$TransactionInterceptor.execute(PersistableRunner.java:565)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.internalExecute(OptimisticLockRetryInterceptor.java:102)
at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:83)
at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:44)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:73)
at org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:45)
at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:39)
at org.jbpm.runtime.manager.impl.error.ExecutionErrorHandlerInterceptor.internalExecute(ExecutionErrorHandlerInterceptor.java:66) at org.jbpm.runtime.manager.impl.error.ExecutionErrorHandlerInterceptor.execute(ExecutionErrorHandlerInterceptor.java:52)
at org.jbpm.runtime.manager.impl.error.ExecutionErrorHandlerInterceptor.execute(ExecutionErrorHandlerInterceptor.java:29)
at org.drools.persistence.PersistableRunner.execute(PersistableRunner.java:400)
at org.drools.persistence.PersistableRunner.execute(PersistableRunner.java:68)
at org.drools.core.runtime.InternalLocalRunner.execute(InternalLocalRunner.java:37)
at org.drools.core.runtime.InternalLocalRunner.execute(InternalLocalRunner.java:41)
at org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession.abortProcessInstance(CommandBasedStatefulKnowledgeSession.java:153)
at org.jbpm.kie.services.impl.ProcessServiceImpl.abortProcessInstance(ProcessServiceImpl.java:220) ... 58 common frames omitted
When aborting a case, it loops through all its subcases and:
- Aborts subcases workitems (this removes the workitems from the Entity Manager), including those from the parent. Though the parents one have a handler linked to them before removing it from the emf, so it waits before removing the entity from the emf https://github.com/kiegroup/drools/blob/master/drools-persistence/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/processinstance/JPAWorkItemManager.java#L121.
- Subcases workitems get removed from the emf https://github.com/kiegroup/drools/blob/master/drools-persistence/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/processinstance/JPAWorkItemManager.java#L131
- Notifies parent case which wa on hold and completes its corresponding work item (meaning this work item gets removed from the entity manager as well): https://github.com/kiegroup/drools/blob/master/drools-persistence/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/processinstance/JPAWorkItemManager.java#L169
- Now the work item mentioned in step 1, continues from where it was left and tries to remove the work item from the emf - but now it is no longer there, therefore the exception arises. https://github.com/kiegroup/drools/blob/master/drools-persistence/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/processinstance/JPAWorkItemManager.java#L131
IMHO as a possible solution we could either:
- Before calling "context.remove" from the internalAbortWorkItem method, we should check again whether the entity is there or has been already removed by the handler in JPAWorkItemManager class: https://github.com/kiegroup/drools/blob/master/drools-persistence/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/processinstance/JPAWorkItemManager.java#L131
- Before removing any entity in the "remove" method from the JpaPersistenceContext class, check whether the entity has been removed from the emf. Though it might not be ideal for all cases: https://github.com/kiegroup/drools/blob/master/drools-persistence/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/JpaPersistenceContext.java#L142
- In jBPM, do not call abortWorkItem when this entity has been already completed.
- is related to
-
RHPAM-3160 Detached WorkItemInfo entities error when aborting cases containing active/running subcases
- Closed