diff --git a/modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/history/HistoricCaseInstanceQuery.java b/modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/history/HistoricCaseInstanceQuery.java index c9360327052..d157d14a720 100644 --- a/modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/history/HistoricCaseInstanceQuery.java +++ b/modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/history/HistoricCaseInstanceQuery.java @@ -450,6 +450,16 @@ public interface HistoricCaseInstanceQuery extends Query historicCaseInstances = query.listPage(0, batchSize); + List historicCaseInstances = query.withoutSorting().returnIdsOnly().listPage(0, batchSize); ObjectNode resultNode = engineConfiguration.getObjectMapper().createObjectNode(); Set caseInstanceIdsToDelete = new HashSet<>(); for (HistoricCaseInstance historicCaseInstance : historicCaseInstances) { diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java index ce5e1f2a12c..43ef38d276f 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java @@ -114,6 +114,8 @@ public class HistoricCaseInstanceQueryImpl extends AbstractVariableQueryImpl executeList(CommandContext commandContext) { ensureVariablesInitialized(); + + if (withoutSorting) { + setIgnoreOrderBy(); + } + List results; - if (includeCaseVariables) { + if (returnIdsOnly) { + results = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager().findIdsByCriteria(this); + + } else if (includeCaseVariables) { results = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager().findWithVariablesByQueryCriteria(this); if (caseInstanceId != null) { @@ -1175,6 +1185,18 @@ public HistoricCaseInstanceQuery withLocalizationFallback() { this.withLocalizationFallback = true; return this; } + + @Override + public HistoricCaseInstanceQuery withoutSorting() { + this.withoutSorting = true; + return this; + } + + @Override + public HistoricCaseInstanceQuery returnIdsOnly() { + this.returnIdsOnly = true; + return this; + } public String getCaseDefinitionId() { return caseDefinitionId; diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManager.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManager.java index 9bd717f3805..f86c6f66a1d 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManager.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManager.java @@ -37,6 +37,8 @@ public interface HistoricCaseInstanceEntityManager extends EntityManager findByCriteria(HistoricCaseInstanceQuery query); List findWithVariablesByQueryCriteria(HistoricCaseInstanceQuery query); + + List findIdsByCriteria(HistoricCaseInstanceQuery query); long countByCriteria(HistoricCaseInstanceQuery query); diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManagerImpl.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManagerImpl.java index 61c9929e55f..a5a2b4780a4 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManagerImpl.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/HistoricCaseInstanceEntityManagerImpl.java @@ -65,6 +65,11 @@ public List findByCriteria(HistoricCaseInstanceQuery query public List findWithVariablesByQueryCriteria(HistoricCaseInstanceQuery query) { return dataManager.findWithVariablesByQueryCriteria((HistoricCaseInstanceQueryImpl) query); } + + @Override + public List findIdsByCriteria(HistoricCaseInstanceQuery query) { + return dataManager.findIdsByCriteria((HistoricCaseInstanceQueryImpl) query); + } @Override public long countByCriteria(HistoricCaseInstanceQuery query) { diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/HistoricCaseInstanceDataManager.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/HistoricCaseInstanceDataManager.java index 271299e1caa..4b14883c7f7 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/HistoricCaseInstanceDataManager.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/HistoricCaseInstanceDataManager.java @@ -37,6 +37,8 @@ public interface HistoricCaseInstanceDataManager extends DataManager findWithVariablesByQueryCriteria(HistoricCaseInstanceQueryImpl historicCaseInstanceQuery); + + List findIdsByCriteria(HistoricCaseInstanceQueryImpl query); void deleteByCaseDefinitionId(String caseDefinitionId); diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/impl/MybatisHistoricCaseInstanceDataManagerImpl.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/impl/MybatisHistoricCaseInstanceDataManagerImpl.java index 1171fb7df9e..5482d83f990 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/impl/MybatisHistoricCaseInstanceDataManagerImpl.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/impl/MybatisHistoricCaseInstanceDataManagerImpl.java @@ -82,6 +82,12 @@ public List findWithVariablesByQueryCriteria(HistoricCaseI return getDbSqlSession().selectList("selectHistoricCaseInstancesWithVariablesByQueryCriteria", historicCaseInstanceQuery, getManagedEntityClass()); } + @Override + @SuppressWarnings("unchecked") + public List findIdsByCriteria(HistoricCaseInstanceQueryImpl query) { + setSafeInValueLists(query); + return getDbSqlSession().selectList("selectHistoricCaseInstanceIdsByQueryCriteria", query, getManagedEntityClass()); + } @Override public void deleteByCaseDefinitionId(String caseDefinitionId) { diff --git a/modules/flowable-cmmn-engine/src/main/resources/org/flowable/cmmn/db/mapping/entity/HistoricCaseInstance.xml b/modules/flowable-cmmn-engine/src/main/resources/org/flowable/cmmn/db/mapping/entity/HistoricCaseInstance.xml index eb7ebe4b3d8..5ab80379726 100644 --- a/modules/flowable-cmmn-engine/src/main/resources/org/flowable/cmmn/db/mapping/entity/HistoricCaseInstance.xml +++ b/modules/flowable-cmmn-engine/src/main/resources/org/flowable/cmmn/db/mapping/entity/HistoricCaseInstance.xml @@ -182,6 +182,10 @@ + + + + + + + + from ${prefix}ACT_HI_PROCINST RES @@ -389,7 +400,7 @@ Doing a join on the definition table is OK, since it is a 1:1 relationship. This has to be an outer join because historic data might exists, but definitions might have been deleted --> - left outer join ${prefix}ACT_RE_PROCDEF DEF on RES.PROC_DEF_ID_ = DEF.ID_ + left outer join ${prefix}ACT_RE_PROCDEF DEF on RES.PROC_DEF_ID_ = DEF.ID_ diff --git a/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/history/HistoricProcessInstanceQueryTest.java b/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/history/HistoricProcessInstanceQueryTest.java index 17b125ebde7..4f7d5ae2c02 100644 --- a/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/history/HistoricProcessInstanceQueryTest.java +++ b/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/history/HistoricProcessInstanceQueryTest.java @@ -557,4 +557,58 @@ public void testQueryByParentScopeId() { ); } + @Test + public void testIdQueryByDeploymentId() { + deployOneTaskTestProcess(); + String deploymentId = repositoryService.createDeploymentQuery().singleResult().getId(); + runtimeService.startProcessInstanceByKey("oneTaskProcess"); + if (HistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, processEngineConfiguration)) { + HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().deploymentId(deploymentId).withoutSorting().returnIdsOnly().singleResult(); + assertThat(historicProcessInstance).isNotNull(); + assertThat(historicProcessInstance.getId()).isNotNull(); + assertThat(historicProcessInstance.getDeploymentId()).isNull(); + assertThat(historicProcessInstance.getProcessDefinitionId()).isNull(); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().deploymentId(deploymentId).withoutSorting().singleResult(); + assertThat(historicProcessInstance).isNotNull(); + assertThat(historicProcessInstance.getId()).isNotNull(); + assertThat(historicProcessInstance.getDeploymentId()).isNotNull(); + assertThat(historicProcessInstance.getProcessDefinitionId()).isNotNull(); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().deploymentId(deploymentId).returnIdsOnly().singleResult(); + assertThat(historicProcessInstance).isNotNull(); + assertThat(historicProcessInstance.getId()).isNotNull(); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().deploymentId("nonexisting").returnIdsOnly().singleResult(); + assertThat(historicProcessInstance).isNull(); + } + } + + @Test + public void testIdQueryByInvolvedUser() { + deployOneTaskTestProcess(); + ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder() + .processDefinitionKey("oneTaskProcess") + .start(); + runtimeService.addUserIdentityLink(processInstance.getId(), "kermit", "specialLink"); + + if (HistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, processEngineConfiguration)) { + + HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().involvedUser("kermit", "specialLink").withoutSorting().returnIdsOnly().singleResult(); + assertThat(historicProcessInstance.getId()).isEqualTo(processInstance.getId()); + assertThat(historicProcessInstance.getProcessDefinitionId()).isNull(); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().involvedUser("kermit", "specialLink").withoutSorting().singleResult(); + assertThat(historicProcessInstance.getId()).isEqualTo(processInstance.getId()); + assertThat(historicProcessInstance.getProcessDefinitionId()).isNotNull(); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().or().involvedUser("kermit", "specialLink").processDefinitionKey("undefined").endOr().withoutSorting().returnIdsOnly().singleResult(); + assertThat(historicProcessInstance.getId()).isEqualTo(processInstance.getId()); + assertThat(historicProcessInstance.getProcessDefinitionId()).isNull(); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().or().involvedUser("kermit", "specialLink").processDefinitionKey("undefined").endOr().withoutSorting().singleResult(); + assertThat(historicProcessInstance.getId()).isEqualTo(processInstance.getId()); + assertThat(historicProcessInstance.getProcessDefinitionId()).isNotNull(); + } + } } diff --git a/modules/flowable-engine/src/test/java/org/flowable/engine/test/bpmn/HistoricDataDeleteTest.java b/modules/flowable-engine/src/test/java/org/flowable/engine/test/bpmn/HistoricDataDeleteTest.java index a62967da56d..6fba6da9f4a 100644 --- a/modules/flowable-engine/src/test/java/org/flowable/engine/test/bpmn/HistoricDataDeleteTest.java +++ b/modules/flowable-engine/src/test/java/org/flowable/engine/test/bpmn/HistoricDataDeleteTest.java @@ -1202,6 +1202,8 @@ void testDeleteHistoricInstancesWithAllQueryOptions() throws InvocationTargetExc methodsToIgnore.add("includeProcessVariables"); methodsToIgnore.add("locale"); methodsToIgnore.add("withLocalizationFallback"); + methodsToIgnore.add("withoutSorting"); + methodsToIgnore.add("returnIdsOnly"); methodsToIgnore.add("asc"); methodsToIgnore.add("desc"); methodsToIgnore.add("or"); diff --git a/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisJobDataManager.java b/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisJobDataManager.java index 175c7888b6e..0ba0f373835 100644 --- a/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisJobDataManager.java +++ b/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisJobDataManager.java @@ -21,6 +21,7 @@ import org.flowable.common.engine.impl.cfg.IdGenerator; import org.flowable.common.engine.impl.db.AbstractDataManager; import org.flowable.common.engine.impl.db.DbSqlSession; +import org.flowable.common.engine.impl.db.ListQueryParameterObject; import org.flowable.common.engine.impl.db.SingleCachedEntityMatcher; import org.flowable.common.engine.impl.persistence.cache.CachedEntityMatcher; import org.flowable.job.api.Job; @@ -66,7 +67,10 @@ public List findJobsToExecute(List enabledCategories, Page pa if (enabledCategories != null && enabledCategories.size() > 0) { params.put("enabledCategories", enabledCategories); } - return getDbSqlSession().selectList("selectJobsToExecute", params, page); + + ListQueryParameterObject listQueryParameterObject = new ListQueryParameterObject(params, page.getFirstResult(), page.getMaxResults()); + listQueryParameterObject.setIgnoreOrderBy(); + return getDbSqlSession().selectList("selectJobsToExecute", listQueryParameterObject); } @Override @@ -103,7 +107,10 @@ public List findExpiredJobs(List enabledCategories, Page page if (enabledCategories != null && enabledCategories.size() > 0) { params.put("enabledCategories", enabledCategories); } - return getDbSqlSession().selectList("selectExpiredJobs", params, page); + + ListQueryParameterObject listQueryParameterObject = new ListQueryParameterObject(params, page.getFirstResult(), page.getMaxResults()); + listQueryParameterObject.setIgnoreOrderBy(); + return getDbSqlSession().selectList("selectExpiredJobs", listQueryParameterObject); } @Override diff --git a/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisTimerJobDataManager.java b/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisTimerJobDataManager.java index a33c30a0b4f..e1399764a20 100644 --- a/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisTimerJobDataManager.java +++ b/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/persistence/entity/data/impl/MybatisTimerJobDataManager.java @@ -21,6 +21,7 @@ import org.flowable.common.engine.impl.cfg.IdGenerator; import org.flowable.common.engine.impl.db.AbstractDataManager; import org.flowable.common.engine.impl.db.DbSqlSession; +import org.flowable.common.engine.impl.db.ListQueryParameterObject; import org.flowable.common.engine.impl.db.SingleCachedEntityMatcher; import org.flowable.common.engine.impl.persistence.cache.CachedEntityMatcher; import org.flowable.job.api.Job; @@ -89,7 +90,10 @@ public List findExpiredJobs(List enabledCategories, Page if (enabledCategories != null && enabledCategories.size() > 0) { params.put("enabledCategories", enabledCategories); } - return getDbSqlSession().selectList("selectExpiredTimerJobs", params, page); + + ListQueryParameterObject listQueryParameterObject = new ListQueryParameterObject(params, page.getFirstResult(), page.getMaxResults()); + listQueryParameterObject.setIgnoreOrderBy(); + return getDbSqlSession().selectList("selectExpiredTimerJobs", listQueryParameterObject); } @Override @@ -113,7 +117,10 @@ public List findJobsToExecute(List enabledCategories, Pa if (enabledCategories != null && enabledCategories.size() > 0) { params.put("enabledCategories", enabledCategories); } - return getDbSqlSession().selectList("selectTimerJobsToExecute", params, page); + + ListQueryParameterObject listQueryParameterObject = new ListQueryParameterObject(params, page.getFirstResult(), page.getMaxResults()); + listQueryParameterObject.setIgnoreOrderBy(); + return getDbSqlSession().selectList("selectTimerJobsToExecute", listQueryParameterObject); } @Override diff --git a/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/Job.xml b/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/Job.xml index 18233badc12..ab24cf1c5b5 100755 --- a/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/Job.xml +++ b/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/Job.xml @@ -69,7 +69,6 @@ - ${orderBy} ${limitAfter} @@ -92,7 +91,6 @@ - ${orderBy} ${limitAfter} diff --git a/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/TimerJob.xml b/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/TimerJob.xml index 53f7a5dd1e1..1999c51a8e5 100644 --- a/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/TimerJob.xml +++ b/modules/flowable-job-service/src/main/resources/org/flowable/job/service/db/mapping/entity/TimerJob.xml @@ -191,7 +191,6 @@ #{category, jdbcType=VARCHAR} - ${orderBy} ${limitAfter} @@ -215,7 +214,6 @@ - ${orderBy} ${limitAfter}