flowable/flowable-engine · error · FlowableIllegalArgumentException
EntityManagerFactory must implement 'jakarta.persistence.Ent
Error message
EntityManagerFactory must implement 'jakarta.persistence.EntityManagerFactory'
What it means
EntityManagerSessionFactory's constructor performs an instanceof check after the null check: the argument must implement jakarta.persistence.EntityManagerFactory, otherwise FlowableIllegalArgumentException 'EntityManagerFactory must implement jakarta.persistence.EntityManagerFactory' is thrown.
Source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/EntityManagerSessionFactory.java:37
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.common.engine.impl.interceptor.Session;
import org.flowable.common.engine.impl.interceptor.SessionFactory;
/**
* @author Frederik Heremans
*/
public class EntityManagerSessionFactory implements SessionFactory {
protected EntityManagerFactory entityManagerFactory;
protected boolean handleTransactions;
protected boolean closeEntityManager;
public EntityManagerSessionFactory(Object entityManagerFactory, boolean handleTransactions, boolean closeEntityManager) {
if (entityManagerFactory == null) {
throw new FlowableIllegalArgumentException("entityManagerFactory is null");
}
if (!(entityManagerFactory instanceof EntityManagerFactory)) {
throw new FlowableIllegalArgumentException("EntityManagerFactory must implement 'jakarta.persistence.EntityManagerFactory'");
}
this.entityManagerFactory = (EntityManagerFactory) entityManagerFactory;
this.handleTransactions = handleTransactions;
this.closeEntityManager = closeEntityManager;
}
@Override
public Class<?> getSessionType() {
return EntityManagerSession.class;
}
@Override
public Session openSession(CommandContext commandContext) {
return new EntityManagerSessionImpl(entityManagerFactory, handleTransactions, closeEntityManager);
}
public EntityManagerFactory getEntityManagerFactory() {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a jakarta.persistence.EntityManagerFactory (e.g. Spring's LocalContainerEntityManagerFactoryBean.getObject() or Persistence.createEntityManagerFactory(...))
- Upgrade to Hibernate 5.5+/6 or Spring Boot 3 so the factory implements jakarta.persistence.EntityManagerFactory
- If stuck on javax.persistence, use a Flowable version matching that era (pre-jakarta) rather than mixing libraries
Example fix
// before engineConfig.setJpaEntityManagerFactory(hibernateSessionFactory); // wrong type // after EntityManagerFactory emf = LocalContainerEntityManagerFactoryBean.getObject(); engineConfig.setJpaEntityManagerFactory(emf); // jakarta.persistence.EntityManagerFactory
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(candidate instanceof jakarta.persistence.EntityManagerFactory)) {
throw new IllegalArgumentException(
"expected jakarta.persistence.EntityManagerFactory but got " + candidate.getClass().getName());
} Type guard
boolean isJakartaEmf(Object o) {
return o instanceof jakarta.persistence.EntityManagerFactory;
} Try / catch
try {
config.setJpaEntityManagerFactory(candidate);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
if (e.getMessage().contains("EntityManagerFactory must implement")) {
throw new IllegalStateException(
"pass a jakarta.persistence.EntityManagerFactory (upgrade to Hibernate 5.5+/Spring Boot 3 if using javax)", e);
}
throw e;
} Prevention
- After migrating to Jakarta, check that your ORM (Hibernate 5.5+/6) implements jakarta.persistence interfaces
- Never pass provider-native objects (e.g. Hibernate SessionFactory) where an EntityManagerFactory is required
- Assert the injected bean type in Spring config before building the process engine
When it happens
Trigger: Passing an object that is not a jakarta.persistence.EntityManagerFactory (e.g. a Hibernate-specific SessionFactory, a Spring proxy of the wrong type, or a javax.persistence.EntityManagerFactory from a pre-Jakarta / older Flowable version).
Common situations: Migrating from Java EE (javax.persistence) to Jakarta (jakarta.persistence) — old Hibernate 5 / Spring Boot 2 factories no longer qualify; passing Hibernate's SessionFactoryImpl directly instead of the JPA EntityManagerFactory; wrong bean autowired.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- entityManagerFactory is null
- Error while flushing EntityManager, illegal state
- Cannot flush EntityManager, an active transaction is require
- Value is not a list of JPA entities:
- EntityManagerFactory must implement 'jakarta.persistence.Ent
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0c9728441dabdc22.
Report an issue: GitHub.