How to get an instance of CmmnExecution of an active CaseExecution?

(Among other things) I want to re-evaluate the sentry conditions of a case execution, queried from the db. I saw that there’s this nice class CmmnExecution that can do all wonderful things. What do i need to do to get an instance of that?

Hi @thentschel,

org.camunda.bpm.engine.impl.cmmn.execution.CmmnExecution is an internal class (note the impl in the package name). It is not supposed to be used by non-Camunda code and the methods you are looking at will most likely not work when called from the outside. Note that setting variables triggers sentry re-evaluation, so maybe you can set a dummy variable as a workaround.

Cheers,
Thorben

Hi Thorben,

thanks for the reply. Yes, I know very well that this is an internal class, but I somewhat hoped that I could instantiate it with some tricks. What I really want to do is implement migration code from one CMMN model version to a new one. It appears I have to dive into the DB and do my manipulation there…

Cheers,
Timo

Hi Timo,

CMMN migration sounds like a useful feature. If you are interested in contributing this, we can help you flesh out the details and give you some pointers how to get going. The result would be a proper API feature that Camunda maintains in future versions. See also https://camunda.org/contribute/ for details on code contributions.

By the way, you can obtain CmmnExecution from CaseExecution by casting. However, most things won’t work outside of an engine command.

Cheers,
Thorben

Thanks, @thorben!

I’ll try casting the

engine.getCaseService().createCaseExecutionQuery().singleResult()

to an instance of CmmnExecution. But how can I persist changes made to the instance? How can I change the CaseDefinitionId?

Btw: We could have a more direct talk at the Community Day or at the Con next week.

That’s a good point and one of the reasons why calling non-API methods alone is not sufficient. Camunda implements a command pattern, i.e. every API interaction is a command (you will find that when you have a look at the service implementations). Around every command, the process engine does cross-cutting things like starting transactions or logging some things. Throughout a command, an entity cache is managed that is always flushed before the command ends. This flush is what makes changes to the database. So, the general approach would be implementing a new command that implements the migration logic and updates the in-memory entities. The existing infrastructure takes care of updating the persisted state. To do this, good knowledge about engine internals is required, so I recommend to study the sources a little and understand how things work in the engine, for example by debugging simple API interactions.

However, there is a specific reason why I think CMMN migration cannot be easily built even when using internal API: A case execution’s definition ID is so far not supposed to be updated, so it is not part of the mybatis object-relational mapping (see camunda-bpm-platform/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/CaseExecution.xml at 7.8.0-alpha3 · camunda/camunda-bpm-platform · GitHub). It is not easily possible to extend these mappings without directly modifying the engine sources. That and the inherent complexity of this topic (e.g. ensuring that the resulting case instance state is consistent) is why I think that having this as a core engine feature makes more sense than building on top of the engine.

Sure, I will be there :slight_smile:

Cheers,
Thorben

@thorben,

sure, I’ll try to understand more of the inner mechanics of the engine and debugging is a good start.

I do agree that unless the OR-mapping supports changing the definition ID, I cannot migrate in a safe way. Nonetheless, in the meantime I could use standard JPA to manipulate the ID directly in the DB (thus unfortunately creating a inconsistent case instance), then load the case execution and migrate it to a consistent state again. I know it’s not the ideal approach, but it’s maybe a start, for now.

Hey @thentschel

I created a solution to migrate caseDefinitionId using JPA. In case you are interested: Best practice: Case instance migration

Cheers,
Stefan