flowable/flowable-engine · error · FlowableException

Error while flushing EntityManager:

Error message

Error while flushing EntityManager: 

What it means

Flowable's EntityManagerSessionImpl wraps a JPA EntityManager used to persist JPA-typed variables. When the session flushes at the end of a command and the underlying JPA provider throws a PersistenceException (any persistence-layer failure not covered by the more specific IllegalStateException/TransactionRequiredException handlers), it is rethrown wrapped in this FlowableException with the original message appended.

Source

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

    }

    public EntityManagerSessionImpl(EntityManagerFactory entityManagerFactory, boolean handleTransactions, boolean closeEntityManager) {
        this.entityManagerFactory = entityManagerFactory;
        this.handleTransactions = handleTransactions;
        this.closeEntityManager = closeEntityManager;
    }

    @Override
    public void flush() {
        if (entityManager != null && (!handleTransactions || isTransactionActive())) {
            try {
                entityManager.flush();
            } catch (IllegalStateException ise) {
                throw new FlowableException("Error while flushing EntityManager, illegal state", ise);
            } catch (TransactionRequiredException tre) {
                throw new FlowableException("Cannot flush EntityManager, an active transaction is required", tre);
            } catch (PersistenceException pe) {
                throw new FlowableException("Error while flushing EntityManager: " + pe.getMessage(), pe);
            }
        }
    }

    protected boolean isTransactionActive() {
        if (handleTransactions && entityManager.getTransaction() != null) {
            return entityManager.getTransaction().isActive();
        }
        return false;
    }

    @Override
    public void close() {
        if (closeEntityManager && entityManager != null && entityManager.isOpen()) {
            try {
                entityManager.close();
            } catch (IllegalStateException ise) {
                throw new FlowableException("Error while closing EntityManager, may have already been closed or it is container-managed", ise);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the cause chain (FlowableException#getCause) for the real PersistenceException and the JPA provider's constraint/violation details
  2. Fix the entity state that fails flush: resolve constraint violations, duplicate keys, or null mandatory columns
  3. Verify the JPA entity mappings match the actual database schema
  4. Confirm the datasource/DB is reachable and healthy
  5. Ensure flush happens within an active transaction (Flowable command context provides one)

Example fix

// before
try {
    variableScope.setVariable("customer", detachedEntity);
} catch (FlowableException e) {
    log.error(e.getMessage()); // message is generic
}
// after
try {
    variableScope.setVariable("customer", managedOrValidEntity);
} catch (FlowableException e) {
    log.error("JPA flush failed", e.getCause()); // log root PersistenceException
    throw new BusinessException("Invalid customer entity: " + e.getCause().getMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate entity before setVariable
if (entity == null) throw new IllegalArgumentException("entity required");
// e.g. constraint pre-checks, required fields
Objects.requireNonNull(entity.getId(), "id must be set before persisting as variable");

Type guard

boolean isFlushSafe(Object e) { return e != null && e.getClass().isAnnotationPresent(jakarta.persistence.Entity.class); }

Try / catch

try { runtimeService.setVariable(executionId, "customer", entity); } catch (FlowableException e) { Throwable root = e.getCause(); log.error("JPA flush failed: {}", root != null ? root.getMessage() : e.getMessage(), root); throw new BusinessException("Entity failed to persist", e); }

Prevention

When it happens

Trigger: Calling FlowableException-producing operations (e.g. setting/reading JPA variables via VariableService) when entityManager.flush() throws a PersistenceException: constraint violations, optimistic-lock failures, SQL errors, or mapping problems detected at flush time.

Common situations: Entity violates a DB unique/foreign-key constraint; JPA entity mapping mismatch with the schema; optimistic locking @Version conflict; underlying datasource down; flush occurs inside a Flowable command whose JPA entity state became inconsistent.

Related errors


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