flowable / flowable/flowable-engine
Unexpected result when a HistoricProcessInstanceQuery is executed twice for the same processInstanceId in the same transaction.
- Lingua principale
- Java
- Stelle
- 9.5k
- Fork
- 2.9k
- Merge medio
- 7h 8m
- PR unite (30g)
- 2
Descrizione
**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?
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Direzione di ricerca
Inizia da HistoricProcessInstanceQueryImpl e dal punto di ingresso queryWithRawParameter mostrato nel report; traccia il modo in cui CacheAwareQuery.getId(), entityCache e singleResult() interagiscono tra query ripetute. Confronta la prima e la seconda query nell’esempio di verifica dei permessi, quindi verifica che tutte le clausole della query siano rispettate e che un involvedUser non corrispondente non restituisca l’istanza di processo memorizzata nella cache.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- java
- Ambito
- backend
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100