flowable/flowable-engine · error · ActivitiException

Error while flushing EntityManager, illegal state

Error message

Error while flushing EntityManager, illegal state

What it means

Thrown by EntityManagerSessionImpl.flush() when the underlying JPA EntityManager.flush() call raises IllegalStateException. The engine wraps it in an ActivitiException to surface a JPA lifecycle problem during variable persistence. It means the EntityManager is in a state where flushing is not allowed (e.g. already closed or no active transaction where required by the persistence context).

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/variable/EntityManagerSessionImpl.java:57

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

    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 ActivitiException("Error while flushing EntityManager, illegal state", ise);
            } catch (TransactionRequiredException tre) {
                throw new ActivitiException("Cannot flush EntityManager, an active transaction is required", tre);
            } catch (PersistenceException pe) {
                throw new ActivitiException("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()) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure a JPA transaction is active before the flush: wrap the operation in a transaction (UserTransaction / Spring @Transactional) so isTransactionActive() returns true
  2. Check EntityManagerSessionFactory configuration: set handleTransactions to false when the container manages transactions and lifecycle
  3. Do not close the EntityManager yourself if the engine session owns it (closeEntityManager flag)
  4. Inspect the chained IllegalStateException cause for the exact JPA provider message

Example fix

// before
entityManagerFactory = new EntityManagerSessionFactory(entityManagerFactory, true);
// after: let the container manage transactions
entityManagerFactory = new EntityManagerSessionFactory(entityManagerFactory, false);
Defensive patterns

Strategy: try-catch

Validate before calling

// before flush
EntityManagerSession session = Context.getCommandContext().getSession(EntityManagerSession.class);
if (session != null && session.isTransactionActive()) {
    session.flush();
}

Type guard

if (entityManager != null && entityManager.isOpen() && entityManager.getTransaction() != null && entityManager.getTransaction().isActive()) {
    entityManager.flush();
}

Try / catch

try {
    entityManager.flush();
} catch (ActivitiException e) {
    if (e.getCause() instanceof IllegalStateException) {
        // re-open or re-attach EntityManager / start transaction
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling flush() when handleTransactions is true but the transaction is not active, or when the EntityManager was closed externally (application-managed EM closed before engine flush), or the EM was created by a container that disallows direct flush in the current context.

Common situations: JPA EntityManagerSessionFactory configured with handleTransactions=true but no enclosing transaction (e.g. running a command outside CommandContext transaction management); user code closing the EntityManager before the session flushes; Spring/container-managed EM used in a non-transactional context.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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