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

  1. Pass a jakarta.persistence.EntityManagerFactory (e.g. Spring's LocalContainerEntityManagerFactoryBean.getObject() or Persistence.createEntityManagerFactory(...))
  2. Upgrade to Hibernate 5.5+/6 or Spring Boot 3 so the factory implements jakarta.persistence.EntityManagerFactory
  3. 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

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


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