flowable/flowable-engine · error · FlowableException

Cannot set JPA variable:

Error message

Cannot set JPA variable: 

What it means

JPAEntityListVariableType (and its single-entity sibling) requires an EntityManagerSession to be present in the current command context when a JPA entity is stored as a variable. If Context.getCommandContext().getSession(EntityManagerSession.class) returns null, meaning no JPA persistence context is configured for this engine, it throws this FlowableException.

Source

Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityListVariableType.java:91

                for (Object entity : list) {
                    canStore = entity != null && mappings.isJPAEntity(entity) && mappings.getEntityMetaData(entity.getClass()).getEntityClass().equals(entityClass);
                    if (!canStore) {
                        // In case the object is not a JPA entity or the class
                        // doesn't match, we can't store the list
                        break;
                    }
                }
            }
        }
        return canStore;
    }

    @Override
    public void setValue(Object value, ValueFields valueFields) {
        EntityManagerSession entityManagerSession = Context.getCommandContext().getSession(EntityManagerSession.class);
        if (entityManagerSession == null) {
            throw new FlowableException("Cannot set JPA variable: " + EntityManagerSession.class + " not configured");
        } else {
            // Before we set the value we must flush all pending changes from
            // the entitymanager
            // If we don't do this, in some cases the primary key will not yet
            // be set in the object
            // which will cause exceptions down the road.
            entityManagerSession.flush();
        }

        if (value instanceof List<?> list && list.size() > 0) {
            List<String> ids = new ArrayList<>();

            String type = mappings.getJPAClassString(list.get(0));
            for (Object entry : list) {
                ids.add(mappings.getJPAIdString(entry));
            }

            // Store type in text field and the ID's as a serialized array

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Add jpaPersistenceUnitName (or jpaEntityManagerFactory) to the ProcessEngineConfiguration so an EntityManagerSession is registered
  2. Ensure the same engine that stores the variable is the one with JPA enabled
  3. Verify the variable value type is actually a JPA entity and that JPA variable handling is intended
  4. For tests, configure EntityManagerSessionFactory explicitly in the engine config

Example fix

// before
ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
// after
ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration()
    .setJpaPersistenceUnitName("flowable-jpa-pu");
Defensive patterns

Strategy: validation

Validate before calling

boolean jpaEnabled(ProcessEngine engine) {
    try (Command cmd = null) { /* placeholder */ return true; }
}
// simpler: check config before setting JPA variables
boolean jpaConfigured = processEngineConfig.getJpaEntityManagerFactory() != null
    || processEngineConfig.getJpaPersistenceUnitName() != null;

Try / catch

try { runtimeService.setVariable(executionId, "customer", entity); } catch (FlowableException e) { if (e.getMessage().startsWith("Cannot set JPA variable")) { throw new ConfigurationException("Enable JPA on ProcessEngineConfiguration (jpaPersistenceUnitName)"); } throw e; }

Prevention

When it happens

Trigger: Calling setValue for a variable whose value is a JPA entity/list (e.g. taskService.setVariable(..., entity)) on an engine whose process engine configuration lacks jpaPersistenceUnitName/jpaEntityManagerFactory, so no EntityManagerSession exists.

Common situations: Forgetting to set jpaPersistenceUnitName or jpaEntityManagerFactory in the ProcessEngineConfiguration; setting a JPA entity variable through a secondary engine instance without JPA enabled; unit tests that build the engine config without JPA.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/c3ce07db05608ffa. Report an issue: GitHub.