flowable / flowable/flowable-engine

Unexpected result when a HistoricProcessInstanceQuery is executed twice for the same processInstanceId in the same transaction.

Open
#3,515 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
7h 8m
Merged PRs (30d)
2

Description

**Describe the bug**
When a HistoricProcessInstanceQueryImpl executes (using singleResult()) it finds a HistoricProcessInstance and puts it in its cache. A later executed query in the same transaction with the same processInstanceId does not take any extra clauses into account.

This bug potentially exists in a lot of different query-implementations in flowable. (for example the HistoricTaskInstaceQueryImpl.

We stumbled upon this in a service task delegate which did a permission check by querying a processInstance with an or().involvedUser(username). Got completely lost when the query returned a processInstance when I expected null since no HistoricIdentityLinks existed for the involved user.

When debugging I found the following code:
```
public List queryWithRawParameter(String statement, CacheAwareQuery parameter, Class entityClass, boolean cacheLoadAndStore) {
if (parameter.getId() != null && !parameter.getId().isEmpty()) {
Object entity = entityCache.findInCache(entityClass, parameter.getId());
if (entity != null) {
List resultList = new ArrayList<>();
// enhance the cached entity
parameter.enhanceCachedValue(entity);
resultList.add(entity);
return resultList;
}
}

return selectListWithRawParameter(statement, parameter, cacheLoadAndStore);
}
```
The parameter that comes in is the HistoricProcessInstanceQuery, and the implementation of CacheAwareQuery.getId() is the following:

```
@Override
public String getId() {
return processInstanceId;
}
```
So basically whats happening here is that the second time we issue a HistoricProcessInstanceQuery in the same transaction but with a totally different (except for the processInstanceId) query object, the clauses in the query is completely ignored. :(

**Expected behavior**
I would have expected to not get null back from my query since the involvedUser is not having any HistoricIdentityLinks connected to the HistoricProcessInstance.

**Code**
```
public boolean hasPermissionToViewProcess(String processInstanceId, String userId) {
List groups = candidateManager.getGroupsForCandidateUser(userId);

HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId)
.or()
.involvedUser(userId);

if (!groups.isEmpty()) {
query.involvedGroups(new HashSet<>(groups));
}
query.endOr();

HistoricProcessInstance processInstance = query.singleResult();
return processInstance != null;
}
```

**Additional context**
Flowable 6.7.2
Postgres 11
SpringBoot-application.

How do we disable this cache?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.