Skip to content

Commit 888eef6

Browse files
committed
Use CmmnHistoryManager when deleting case instances through CMMN deployment cascade
The cascade path in CaseDefinitionEntityManagerImpl previously called CmmnHistoryHelper.deleteHistoricCaseInstance directly, bypassing the cmmnHistoryManager.recordHistoricCaseInstanceDeleted hook. Custom history managers (e.g. composite managers subscribing to cleanup events) were silently skipped when a deployment was cascade-deleted, diverging from the BPMN equivalent in ExecutionEntityManagerImpl.deleteProcessInstanceCascade. Mirror BPMN's structure: move the per-instance deletion logic into DefaultCmmnHistoryManager.recordHistoricCaseInstanceDeleted, recursing to this for sub-cases. The cascade caller now invokes the manager hook directly. The static CmmnHistoryHelper.deleteHistoricCaseInstance is removed since all its callers are gone; bulkDeleteHistoricCaseInstances is unchanged (its entry points already go through the manager hook).
1 parent 69f5e9c commit 888eef6

3 files changed

Lines changed: 44 additions & 45 deletions

File tree

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/CmmnHistoryHelper.java

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,63 +16,24 @@
1616
import java.util.List;
1717

1818
import org.flowable.cmmn.engine.CmmnEngineConfiguration;
19-
import org.flowable.cmmn.engine.impl.persistence.entity.HistoricCaseInstanceEntity;
2019
import org.flowable.cmmn.engine.impl.persistence.entity.HistoricCaseInstanceEntityManager;
2120
import org.flowable.cmmn.engine.impl.persistence.entity.HistoricMilestoneInstanceEntityManager;
2221
import org.flowable.cmmn.engine.impl.persistence.entity.HistoricPlanItemInstanceEntityManager;
2322
import org.flowable.cmmn.engine.impl.task.TaskHelper;
2423
import org.flowable.common.engine.api.scope.ScopeTypes;
2524
import org.flowable.common.engine.impl.util.CollectionUtil;
2625
import org.flowable.identitylink.service.HistoricIdentityLinkService;
27-
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntity;
2826
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntityManager;
2927

3028
/**
3129
* Contains logic that is shared by multiple classes around history.
32-
*
30+
*
3331
* @author Joram Barrez
3432
*/
3533
public class CmmnHistoryHelper {
36-
37-
public static final int MAX_SUB_CASE_INSTANCES = 1000;
38-
39-
public static void deleteHistoricCaseInstance(CmmnEngineConfiguration cmmnEngineConfiguration, String caseInstanceId) {
40-
HistoricCaseInstanceEntityManager historicCaseInstanceEntityManager = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager();
41-
HistoricCaseInstanceEntity historicCaseInstance = historicCaseInstanceEntityManager.findById(caseInstanceId);
42-
43-
HistoricMilestoneInstanceEntityManager historicMilestoneInstanceEntityManager = cmmnEngineConfiguration.getHistoricMilestoneInstanceEntityManager();
44-
historicMilestoneInstanceEntityManager.findHistoricMilestoneInstancesByQueryCriteria(new HistoricMilestoneInstanceQueryImpl().milestoneInstanceCaseInstanceId(historicCaseInstance.getId()))
45-
.forEach(m -> historicMilestoneInstanceEntityManager.delete(m.getId()));
46-
47-
HistoricPlanItemInstanceEntityManager historicPlanItemInstanceEntityManager = cmmnEngineConfiguration.getHistoricPlanItemInstanceEntityManager();
48-
historicPlanItemInstanceEntityManager.findByCriteria(new HistoricPlanItemInstanceQueryImpl().planItemInstanceCaseInstanceId(historicCaseInstance.getId()))
49-
.forEach(p -> historicPlanItemInstanceEntityManager.delete(p.getId()));
50-
51-
HistoricIdentityLinkService historicIdentityLinkService = cmmnEngineConfiguration.getIdentityLinkServiceConfiguration().getHistoricIdentityLinkService();
52-
historicIdentityLinkService.deleteHistoricIdentityLinksByScopeIdAndScopeType(historicCaseInstance.getId(), ScopeTypes.CMMN);
53-
historicIdentityLinkService.deleteHistoricIdentityLinksByScopeIdAndScopeType(historicCaseInstance.getId(), ScopeTypes.PLAN_ITEM);
54-
55-
if (cmmnEngineConfiguration.isEnableEntityLinks()) {
56-
cmmnEngineConfiguration.getEntityLinkServiceConfiguration().getHistoricEntityLinkService()
57-
.deleteHistoricEntityLinksByScopeIdAndScopeType(historicCaseInstance.getId(), ScopeTypes.CMMN);
58-
}
59-
60-
HistoricVariableInstanceEntityManager historicVariableInstanceEntityManager = cmmnEngineConfiguration.getVariableServiceConfiguration().getHistoricVariableInstanceEntityManager();
61-
List<HistoricVariableInstanceEntity> historicVariableInstanceEntities = historicVariableInstanceEntityManager
62-
.findHistoricalVariableInstancesByScopeIdAndScopeType(caseInstanceId, ScopeTypes.CMMN);
63-
for (HistoricVariableInstanceEntity historicVariableInstanceEntity : historicVariableInstanceEntities) {
64-
historicVariableInstanceEntityManager.delete(historicVariableInstanceEntity);
65-
}
66-
67-
TaskHelper.deleteHistoricTaskInstancesByCaseInstanceId(caseInstanceId, cmmnEngineConfiguration);
6834

69-
historicCaseInstanceEntityManager.delete(historicCaseInstance);
35+
public static final int MAX_SUB_CASE_INSTANCES = 1000;
7036

71-
// Also delete any sub cases that may be active
72-
historicCaseInstanceEntityManager.createHistoricCaseInstanceQuery().caseInstanceParentId(caseInstanceId).list()
73-
.forEach(c -> deleteHistoricCaseInstance(cmmnEngineConfiguration, c.getId()));
74-
}
75-
7637
public static void bulkDeleteHistoricCaseInstances(Collection<String> caseInstanceIds, CmmnEngineConfiguration cmmnEngineConfiguration) {
7738
HistoricCaseInstanceEntityManager historicCaseInstanceEntityManager = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager();
7839

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/DefaultCmmnHistoryManager.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.flowable.cmmn.model.Stage;
3838
import org.flowable.common.engine.api.FlowableException;
3939
import org.flowable.common.engine.api.delegate.Expression;
40+
import org.flowable.common.engine.api.scope.ScopeTypes;
4041
import org.flowable.common.engine.impl.identity.Authentication;
4142
import org.flowable.entitylink.api.history.HistoricEntityLinkService;
4243
import org.flowable.entitylink.service.impl.persistence.entity.EntityLinkEntity;
@@ -51,6 +52,8 @@
5152
import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl;
5253
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
5354
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
55+
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntity;
56+
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntityManager;
5457
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntity;
5558

5659
/**
@@ -191,9 +194,44 @@ public void recordMilestoneReached(MilestoneInstanceEntity milestoneInstance) {
191194
@Override
192195
public void recordHistoricCaseInstanceDeleted(String caseInstanceId, String tenantId) {
193196
if (getHistoryConfigurationSettings().isHistoryEnabled()) {
194-
CmmnHistoryHelper.deleteHistoricCaseInstance(cmmnEngineConfiguration, caseInstanceId);
197+
HistoricCaseInstanceEntityManager historicCaseInstanceEntityManager = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager();
198+
HistoricCaseInstanceEntity historicCaseInstance = historicCaseInstanceEntityManager.findById(caseInstanceId);
199+
200+
HistoricMilestoneInstanceEntityManager historicMilestoneInstanceEntityManager = cmmnEngineConfiguration.getHistoricMilestoneInstanceEntityManager();
201+
historicMilestoneInstanceEntityManager.findHistoricMilestoneInstancesByQueryCriteria(
202+
new HistoricMilestoneInstanceQueryImpl().milestoneInstanceCaseInstanceId(historicCaseInstance.getId()))
203+
.forEach(m -> historicMilestoneInstanceEntityManager.delete(m.getId()));
204+
205+
HistoricPlanItemInstanceEntityManager historicPlanItemInstanceEntityManager = cmmnEngineConfiguration.getHistoricPlanItemInstanceEntityManager();
206+
historicPlanItemInstanceEntityManager.findByCriteria(
207+
new HistoricPlanItemInstanceQueryImpl().planItemInstanceCaseInstanceId(historicCaseInstance.getId()))
208+
.forEach(p -> historicPlanItemInstanceEntityManager.delete(p.getId()));
209+
210+
HistoricIdentityLinkService historicIdentityLinkService = cmmnEngineConfiguration.getIdentityLinkServiceConfiguration().getHistoricIdentityLinkService();
211+
historicIdentityLinkService.deleteHistoricIdentityLinksByScopeIdAndScopeType(historicCaseInstance.getId(), ScopeTypes.CMMN);
212+
historicIdentityLinkService.deleteHistoricIdentityLinksByScopeIdAndScopeType(historicCaseInstance.getId(), ScopeTypes.PLAN_ITEM);
213+
214+
if (cmmnEngineConfiguration.isEnableEntityLinks()) {
215+
cmmnEngineConfiguration.getEntityLinkServiceConfiguration().getHistoricEntityLinkService()
216+
.deleteHistoricEntityLinksByScopeIdAndScopeType(historicCaseInstance.getId(), ScopeTypes.CMMN);
217+
}
218+
219+
HistoricVariableInstanceEntityManager historicVariableInstanceEntityManager = cmmnEngineConfiguration.getVariableServiceConfiguration().getHistoricVariableInstanceEntityManager();
220+
List<HistoricVariableInstanceEntity> historicVariableInstanceEntities = historicVariableInstanceEntityManager
221+
.findHistoricalVariableInstancesByScopeIdAndScopeType(caseInstanceId, ScopeTypes.CMMN);
222+
for (HistoricVariableInstanceEntity historicVariableInstanceEntity : historicVariableInstanceEntities) {
223+
historicVariableInstanceEntityManager.delete(historicVariableInstanceEntity);
224+
}
225+
226+
TaskHelper.deleteHistoricTaskInstancesByCaseInstanceId(caseInstanceId, cmmnEngineConfiguration);
227+
228+
historicCaseInstanceEntityManager.delete(historicCaseInstance);
229+
230+
// Also delete any sub cases that may be active
231+
historicCaseInstanceEntityManager.createHistoricCaseInstanceQuery().caseInstanceParentId(caseInstanceId).list()
232+
.forEach(c -> recordHistoricCaseInstanceDeleted(c.getId(), c.getTenantId()));
195233
}
196-
}
234+
}
197235

198236
@Override
199237
public void recordBulkDeleteHistoricCaseInstances(Collection<String> caseInstanceIds) {

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/CaseDefinitionEntityManagerImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.flowable.cmmn.api.repository.CaseDefinitionQuery;
2222
import org.flowable.cmmn.api.runtime.CaseInstance;
2323
import org.flowable.cmmn.engine.CmmnEngineConfiguration;
24-
import org.flowable.cmmn.engine.impl.history.CmmnHistoryHelper;
2524
import org.flowable.cmmn.engine.impl.history.HistoricCaseInstanceQueryImpl;
2625
import org.flowable.cmmn.engine.impl.history.HistoricMilestoneInstanceQueryImpl;
2726
import org.flowable.cmmn.engine.impl.persistence.entity.data.CaseDefinitionDataManager;
@@ -131,7 +130,8 @@ public void deleteCaseDefinitionAndRelatedData(String caseDefinitionId, boolean
131130
List<HistoricCaseInstance> historicCaseInstanceEntities = historicCaseInstanceEntityManager
132131
.findByCriteria(new HistoricCaseInstanceQueryImpl().caseDefinitionId(caseDefinitionId));
133132
for (HistoricCaseInstance historicCaseInstanceEntity : historicCaseInstanceEntities) {
134-
CmmnHistoryHelper.deleteHistoricCaseInstance(engineConfiguration, historicCaseInstanceEntity.getId());
133+
engineConfiguration.getCmmnHistoryManager()
134+
.recordHistoricCaseInstanceDeleted(historicCaseInstanceEntity.getId(), historicCaseInstanceEntity.getTenantId());
135135
}
136136
}
137137

0 commit comments

Comments
 (0)