flowable / flowable/flowable-engine

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

Aperta
#3,515 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.