From 9f265ea38854909c87acbcfb9f63262595e55693 Mon Sep 17 00:00:00 2001 From: "joram.barrez" Date: Wed, 19 Jul 2023 16:08:30 +0200 Subject: [PATCH] Fix: delete related historic case/process instance to process/case instance using case / process task --- .../impl/cmmn/DefaultCaseInstanceService.java | 10 ++- .../DefaultProcessInstanceService.java | 4 +- .../org/flowable/cmmn/test/CaseTaskTest.java | 74 +++++++++++++++++++ .../flowable/cmmn/test/ProcessTaskTest.java | 29 ++++++++ .../impl/ProcessTaskActivityBehavior.java | 10 +-- .../impl/process/ProcessInstanceService.java | 2 +- .../AbstractCmmnDynamicStateManager.java | 2 +- .../impl/agenda/ContinueProcessOperation.java | 4 +- .../MultiInstanceActivityBehavior.java | 2 +- .../ParallelGatewayActivityBehavior.java | 2 +- .../engine/impl/cmmn/CaseInstanceService.java | 2 +- .../entity/ExecutionEntityManager.java | 2 +- .../entity/ExecutionEntityManagerImpl.java | 12 ++- 13 files changed, 130 insertions(+), 25 deletions(-) diff --git a/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/cmmn/DefaultCaseInstanceService.java b/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/cmmn/DefaultCaseInstanceService.java index 793ef808eb3..a419b41c754 100644 --- a/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/cmmn/DefaultCaseInstanceService.java +++ b/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/cmmn/DefaultCaseInstanceService.java @@ -142,15 +142,19 @@ public void deleteCaseInstancesForExecutionId(String executionId) { } @Override - public void deleteCaseInstanceWithoutAgenda(String caseInstanceId) { + public void deleteCaseInstanceWithoutAgenda(String caseInstanceId, boolean deleteInHistory) { cmmnEngineConfiguration.getCommandExecutor().execute(commandContext -> { CaseInstanceEntity caseInstanceEntity = CommandContextUtil.getCaseInstanceEntityManager(commandContext).findById(caseInstanceId); if (caseInstanceEntity == null || caseInstanceEntity.isDeleted()) { return null; } - cmmnEngineConfiguration.getCmmnHistoryManager().recordCaseInstanceEnd( - caseInstanceEntity, CaseInstanceState.TERMINATED, cmmnEngineConfiguration.getClock().getCurrentTime()); + if (deleteInHistory) { + cmmnEngineConfiguration.getCmmnHistoryManager().recordHistoricCaseInstanceDeleted(caseInstanceId, caseInstanceEntity.getTenantId()); + } else { + cmmnEngineConfiguration.getCmmnHistoryManager().recordCaseInstanceEnd( + caseInstanceEntity, CaseInstanceState.TERMINATED, cmmnEngineConfiguration.getClock().getCurrentTime()); + } cmmnEngineConfiguration.getCaseInstanceEntityManager().delete(caseInstanceEntity.getId(), false, "cmmn-state-transition-delete-case"); diff --git a/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/process/DefaultProcessInstanceService.java b/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/process/DefaultProcessInstanceService.java index f74fd3b3504..5e14c24ba36 100644 --- a/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/process/DefaultProcessInstanceService.java +++ b/modules/flowable-cmmn-engine-configurator/src/main/java/org/flowable/cmmn/engine/configurator/impl/process/DefaultProcessInstanceService.java @@ -148,7 +148,7 @@ public List getOutputParametersOfCaseTask(String executionId) { } @Override - public void deleteProcessInstance(String processInstanceId) { + public void deleteProcessInstance(String processInstanceId, boolean cascade) { processEngineConfiguration.getCommandExecutor().execute(commandContext -> { ExecutionEntity processInstanceEntity = CommandContextUtil.getExecutionEntityManager(commandContext).findById(processInstanceId); @@ -156,7 +156,7 @@ public void deleteProcessInstance(String processInstanceId) { return null; } - CommandContextUtil.getExecutionEntityManager(commandContext).deleteProcessInstance(processInstanceEntity.getProcessInstanceId(), DELETE_REASON, false); + CommandContextUtil.getExecutionEntityManager(commandContext).deleteProcessInstance(processInstanceEntity.getProcessInstanceId(), DELETE_REASON, cascade); return null; }); diff --git a/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/CaseTaskTest.java b/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/CaseTaskTest.java index 90b0db1649d..81bdff704e9 100644 --- a/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/CaseTaskTest.java +++ b/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/CaseTaskTest.java @@ -1259,6 +1259,80 @@ public void testParallelMultiInstanceCaseTask() { } } + @Test + public void testProcessDeploymentDeleteDeletesRelatedCaseInstances() { + Deployment deployment = processEngineRepositoryService.createDeployment() + .addClasspathResource("org/flowable/cmmn/test/caseTaskProcess.bpmn20.xml") + .deploy(); + + org.flowable.cmmn.api.repository.CmmnDeployment cmmnDeployment = cmmnRepositoryService.createDeployment() + .addClasspathResource("org/flowable/cmmn/test/CaseTaskTest.testCaseTask.cmmn") + .deploy(); + + // Start process instance, complete a user task to arrive at the case task + ProcessInstance processInstance = processEngineRuntimeService.startProcessInstanceByKey("caseTask"); + processEngineTaskService.complete(processEngineTaskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult().getId()); + assertThat(processEngineRuntimeService.createProcessInstanceQuery().count()).isOne(); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isOne(); + + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceQuery().singleResult(); + assertThat(caseInstance).isNotNull(); + + if (HistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.AUDIT, (ProcessEngineConfigurationImpl) processEngineConfiguration)) { + assertThat(processEngineHistoryService.createHistoricProcessInstanceQuery().count()).isOne(); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().count()).isOne(); + } + + // Deleting the process deployment also should delete the case instance + processEngineRepositoryService.deleteDeployment(deployment.getId(), true); + + assertThat(processEngineRuntimeService.createProcessInstanceQuery().count()).isZero(); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (HistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.AUDIT, (ProcessEngineConfigurationImpl) processEngineConfiguration)) { + assertThat(processEngineHistoryService.createHistoricProcessInstanceQuery().count()).isZero(); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().count()).isZero(); + } + } + + // TODO: this needs a DB schema change (adding process instance id to historic case instance) +// @Test +// public void testCompletedProcessDeploymentDeleteDeletesRelatedCaseInstances() { +// // Same test as testProcessDeploymentDeleteDeletesRelatedCaseInstances, but now the process instance and case instance are completed +// +// Deployment deployment = processEngineRepositoryService.createDeployment() +// .addClasspathResource("org/flowable/cmmn/test/caseTaskProcess.bpmn20.xml") +// .deploy(); +// +// org.flowable.cmmn.api.repository.CmmnDeployment cmmnDeployment = cmmnRepositoryService.createDeployment() +// .addClasspathResource("org/flowable/cmmn/test/CaseTaskTest.testCaseTask.cmmn") +// .deploy(); +// +// ProcessInstance processInstance = processEngineRuntimeService.startProcessInstanceByKey("caseTask"); +// processEngineTaskService.complete(processEngineTaskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult().getId()); +// cmmnTaskService.complete(cmmnTaskService.createTaskQuery().singleResult().getId()); +// processEngineTaskService.complete(processEngineTaskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult().getId()); +// +// if (HistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.AUDIT, (ProcessEngineConfigurationImpl) processEngineConfiguration)) { +// assertThat(processEngineHistoryService.createHistoricProcessInstanceQuery().count()).isOne(); +// assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().count()).isOne(); +// } +// +// assertThat(processEngineRuntimeService.createProcessInstanceQuery().count()).isZero(); +// assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); +// +// // Deleting the process deployment also should delete the case instance +// processEngineRepositoryService.deleteDeployment(deployment.getId(), true); +// +// assertThat(processEngineRuntimeService.createProcessInstanceQuery().count()).isZero(); +// assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); +// +// if (HistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.AUDIT, (ProcessEngineConfigurationImpl) processEngineConfiguration)) { +// assertThat(processEngineHistoryService.createHistoricProcessInstanceQuery().count()).isZero(); +// assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().count()).isZero(); +// } +// } + static class ClearExecutionReferenceCmd implements Command { diff --git a/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/ProcessTaskTest.java b/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/ProcessTaskTest.java index 3a505125566..956e8df3023 100644 --- a/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/ProcessTaskTest.java +++ b/modules/flowable-cmmn-engine-configurator/src/test/java/org/flowable/cmmn/test/ProcessTaskTest.java @@ -2035,4 +2035,33 @@ public void testDeleteCaseInstanceWithRepeatingProcessTask() { assertThat(cmmnTaskService.createTaskQuery().count()).isZero(); } + @Test + public void testCaseDeploymentDeleteDeletesRelatedProcessInstances() { + org.flowable.cmmn.api.repository.CmmnDeployment cmmnDeployment = cmmnRepositoryService.createDeployment() + .addClasspathResource("org/flowable/cmmn/test/ProcessTaskTest.testOneTaskProcessBlocking.cmmn") + .deploy(); + + // Start case instance, complete a user task to arrive at the case task + startCaseInstanceWithOneTaskProcess(); + + ProcessInstance processInstance = processEngineRuntimeService.createProcessInstanceQuery().singleResult(); + assertThat(processInstance).isNotNull(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().count()).isOne(); + assertThat(processEngineHistoryService.createHistoricProcessInstanceQuery().count()).isOne(); + } + + // Deleting the case deployment also should delete the process instance + cmmnRepositoryService.deleteDeployment(cmmnDeployment.getId(), true); + + assertThat(processEngineRuntimeService.createProcessInstanceQuery().count()).isZero(); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().count()).isZero(); + assertThat(processEngineHistoryService.createHistoricProcessInstanceQuery().count()).isZero(); + } + } + } diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/ProcessTaskActivityBehavior.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/ProcessTaskActivityBehavior.java index 9f4277b9f39..869d52d7e01 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/ProcessTaskActivityBehavior.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/ProcessTaskActivityBehavior.java @@ -157,7 +157,7 @@ public void trigger(CommandContext commandContext, PlanItemInstanceEntity planIt // Triggering the plan item (as opposed to a regular complete) terminates the process instance CommandContextUtil.getAgenda(commandContext).planCompletePlanItemInstanceOperation(planItemInstance); - deleteProcessInstance(commandContext, planItemInstance); + deleteProcessInstance(commandContext, planItemInstance, false); } @Override @@ -165,22 +165,22 @@ public void onStateTransition(CommandContext commandContext, DelegatePlanItemIns if (PlanItemInstanceState.ACTIVE.equals(planItemInstance.getState())) { // The process task plan item will be deleted by the regular TerminatePlanItemOperation if (PlanItemTransition.TERMINATE.equals(transition) || PlanItemTransition.EXIT.equals(transition)) { - deleteProcessInstance(commandContext, planItemInstance); + deleteProcessInstance(commandContext, planItemInstance, false); } } } - protected void deleteProcessInstance(CommandContext commandContext, DelegatePlanItemInstance planItemInstance) { + protected void deleteProcessInstance(CommandContext commandContext, DelegatePlanItemInstance planItemInstance, boolean cascade) { ProcessInstanceService processInstanceService = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getProcessInstanceService(); - processInstanceService.deleteProcessInstance(planItemInstance.getReferenceId()); + processInstanceService.deleteProcessInstance(planItemInstance.getReferenceId(), cascade); } @Override public void deleteChildEntity(CommandContext commandContext, DelegatePlanItemInstance delegatePlanItemInstance, boolean cascade) { if (ReferenceTypes.PLAN_ITEM_CHILD_PROCESS.equals(delegatePlanItemInstance.getReferenceType())) { delegatePlanItemInstance.setState(PlanItemInstanceState.TERMINATED); // This is not the regular termination, but the state still needs to be correct - deleteProcessInstance(commandContext, delegatePlanItemInstance); + deleteProcessInstance(commandContext, delegatePlanItemInstance, cascade); } else { throw new FlowableException("Can only delete a child entity for a plan item with reference type " + ReferenceTypes.PLAN_ITEM_CHILD_PROCESS); } diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/process/ProcessInstanceService.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/process/ProcessInstanceService.java index 20087ffc294..a98a22dc0dd 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/process/ProcessInstanceService.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/process/ProcessInstanceService.java @@ -47,7 +47,7 @@ String startProcessInstanceByKey(String processDefinitionKey, String predefinedP /** * Deletes the given process instance. Typically used to propagate termination. */ - void deleteProcessInstance(String processInstanceId); + void deleteProcessInstance(String processInstanceId, boolean cascade); /** * Returns the variable value for a given variable. diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java index 478af7bc288..9117fb71343 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java @@ -951,7 +951,7 @@ protected void terminatePlanItemInstance(PlanItemInstanceEntity planItemInstance } else if (planItemDefinition instanceof ProcessTask) { if (planItemInstance.getReferenceId() != null) { - cmmnEngineConfiguration.getProcessInstanceService().deleteProcessInstance(planItemInstance.getReferenceId()); + cmmnEngineConfiguration.getProcessInstanceService().deleteProcessInstance(planItemInstance.getReferenceId(), false); } } else if (planItemDefinition instanceof EventListener) { diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/agenda/ContinueProcessOperation.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/agenda/ContinueProcessOperation.java index 9faaaf8d151..b0003b4b80e 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/agenda/ContinueProcessOperation.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/agenda/ContinueProcessOperation.java @@ -140,7 +140,7 @@ protected void createChildExecutionForSubProcess(SubProcess subProcess) { subProcessExecution.setCurrentFlowElement(subProcess); subProcessExecution.setScope(true); - CommandContextUtil.getExecutionEntityManager(commandContext).deleteRelatedDataForExecution(execution, null, false); + CommandContextUtil.getExecutionEntityManager(commandContext).deleteRelatedDataForExecution(execution, null, false, false); CommandContextUtil.getExecutionEntityManager(commandContext).delete(execution); execution = subProcessExecution; } @@ -253,7 +253,7 @@ protected ExecutionEntity createMultiInstanceRootExecution(ExecutionEntity execu FlowElement flowElement = execution.getCurrentFlowElement(); ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(); - executionEntityManager.deleteRelatedDataForExecution(execution, null, false); + executionEntityManager.deleteRelatedDataForExecution(execution, null, false, false); executionEntityManager.delete(execution); ExecutionEntity multiInstanceRootExecution = executionEntityManager.createChildExecution(parentExecution); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/MultiInstanceActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/MultiInstanceActivityBehavior.java index 1842f6adcba..644434022bd 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/MultiInstanceActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/MultiInstanceActivityBehavior.java @@ -266,7 +266,7 @@ protected void cleanupMiRoot(DelegateExecution execution) { ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(); Collection executionIdsNotToSendCancelledEventsFor = execution.isMultiInstanceRoot() ? null : Collections.singletonList(execution.getId()); executionEntityManager.deleteChildExecutions(multiInstanceRootExecution, null, executionIdsNotToSendCancelledEventsFor, DELETE_REASON_END, true, flowElement); - executionEntityManager.deleteRelatedDataForExecution(multiInstanceRootExecution, DELETE_REASON_END, false); + executionEntityManager.deleteRelatedDataForExecution(multiInstanceRootExecution, DELETE_REASON_END, false, false); executionEntityManager.delete(multiInstanceRootExecution); ExecutionEntity newExecution = executionEntityManager.createChildExecution(parentExecution); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ParallelGatewayActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ParallelGatewayActivityBehavior.java index ed2c656c030..4a11bba3c45 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ParallelGatewayActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ParallelGatewayActivityBehavior.java @@ -103,7 +103,7 @@ public void execute(DelegateExecution execution) { // The current execution will be reused and not deleted if (!joinedExecution.getId().equals(execution.getId())) { - executionEntityManager.deleteRelatedDataForExecution(joinedExecution, null, false); + executionEntityManager.deleteRelatedDataForExecution(joinedExecution, null, false, false); executionEntityManager.delete(joinedExecution); } diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmmn/CaseInstanceService.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmmn/CaseInstanceService.java index c8a66b97d99..3dadb84c2df 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmmn/CaseInstanceService.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmmn/CaseInstanceService.java @@ -37,6 +37,6 @@ String startCaseInstanceByKey(String caseDefinitionKey, String predefinedCaseIns void deleteCaseInstancesForExecutionId(String executionId); - void deleteCaseInstanceWithoutAgenda(String caseInstanceId); + void deleteCaseInstanceWithoutAgenda(String caseInstanceId, boolean deleteInHistory); } diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManager.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManager.java index 34ad8157e59..246ab708d66 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManager.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManager.java @@ -113,7 +113,7 @@ void deleteExecutionAndRelatedData(ExecutionEntity executionEntity, String delet void deleteExecutionAndRelatedData(ExecutionEntity executionEntity, String deleteReason, boolean deleteHistory); - void deleteRelatedDataForExecution(ExecutionEntity executionEntity, String deleteReason, boolean directDeleteInDatabase); + void deleteRelatedDataForExecution(ExecutionEntity executionEntity, String deleteReason, boolean deleteHistory, boolean directDeleteInDatabase); void updateProcessInstanceLockTime(String processInstanceId, String lockOwner, Date lockTime); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java index 9f274b6c357..2f292cc7ede 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java @@ -561,7 +561,7 @@ public void deleteExecutionAndRelatedData(ExecutionEntity executionEntity, Strin CommandContextUtil.getActivityInstanceEntityManager().recordActivityEnd(executionEntity, deleteReason); } - deleteRelatedDataForExecution(executionEntity, deleteReason, directDeleteInDatabase); + deleteRelatedDataForExecution(executionEntity, deleteReason, deleteHistory, directDeleteInDatabase); delete(executionEntity); if (cancel && !executionEntity.isProcessInstanceType()) { @@ -817,10 +817,8 @@ public ExecutionEntity findFirstMultiInstanceRoot(ExecutionEntity executionEntit return null; } - protected CachedEntityMatcher identityLinkByProcessInstanceMatcher = new IdentityLinksByProcessInstanceMatcher(); - @Override - public void deleteRelatedDataForExecution(ExecutionEntity executionEntity, String deleteReason, boolean directDeleteInDatabase) { + public void deleteRelatedDataForExecution(ExecutionEntity executionEntity, String deleteReason, boolean deleteHistory, boolean directDeleteInDatabase) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Ending and deleting execution {} Reason: {}", executionEntity, deleteReason); } @@ -843,16 +841,16 @@ public void deleteRelatedDataForExecution(ExecutionEntity executionEntity, Strin deleteJobs(executionEntity, commandContext, enableExecutionRelationshipCounts, eventDispatcherEnabled); deleteEventSubScriptions(executionEntity, enableExecutionRelationshipCounts, eventDispatcherEnabled); deleteActivityInstances(executionEntity, commandContext); - deleteSubCases(executionEntity, directDeleteInDatabase, commandContext); + deleteSubCases(executionEntity, deleteHistory, directDeleteInDatabase, commandContext); } - protected void deleteSubCases(ExecutionEntity executionEntity, boolean directDeleteInDatabase, CommandContext commandContext) { + protected void deleteSubCases(ExecutionEntity executionEntity, boolean deleteHistory, boolean directDeleteInDatabase, CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); CaseInstanceService caseInstanceService = processEngineConfiguration.getCaseInstanceService(); if (caseInstanceService != null) { if (executionEntity.getReferenceId() != null && ReferenceTypes.EXECUTION_CHILD_CASE.equals(executionEntity.getReferenceType())) { if (directDeleteInDatabase) { - caseInstanceService.deleteCaseInstanceWithoutAgenda(executionEntity.getReferenceId()); + caseInstanceService.deleteCaseInstanceWithoutAgenda(executionEntity.getReferenceId(), deleteHistory); } else { caseInstanceService.deleteCaseInstance(executionEntity.getReferenceId()); }