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
- Inspect the cause chain (FlowableException#getCause) for the real PersistenceException and the JPA provider's constraint/violation details
- Fix the entity state that fails flush: resolve constraint violations, duplicate keys, or null mandatory columns
- Verify the JPA entity mappings match the actual database schema
- Confirm the datasource/DB is reachable and healthy
- 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
- Always log/inspect FlowableException.getCause() — the real JPA failure is in the cause chain
- Validate entity constraints (uniques, required fields) before storing as variable
- Keep DB schema and entity mappings in sync (schema validation in tests)
- Ensure entities are managed/persisted before flush at variable write time
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
- Error while flushing EntityManager, illegal state
- Cannot flush EntityManager, an active transaction is require
- Error while flushing EntityManager: " + pe.getMessage()
- There are app definitions with key = '' and version = ''
- There are ${count} decision tables with key = '${decisionKey
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/eceb9714e92f710c.
Report an issue: GitHub.