flowable/flowable-engine · error · ActivitiIllegalArgumentException
EntityManagerFactory must implement 'jakarta.persistence.Ent
Error message
EntityManagerFactory must implement 'jakarta.persistence.EntityManagerFactory'
What it means
EntityManagerSessionFactory's constructor type-checks the entityManagerFactory argument against jakarta.persistence.EntityManagerFactory and throws ActivitiIllegalArgumentException if it is any other type. This catches callers passing a wrong-typed object (e.g. a Hibernate SessionFactory or a javax version of EntityManagerFactory after a namespace migration).
Source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/variable/EntityManagerSessionFactory.java:37
import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.flowable.variable.service.impl.types.EntityManagerSession;
/**
* @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 ActivitiIllegalArgumentException("entityManagerFactory is null");
}
if (!(entityManagerFactory instanceof EntityManagerFactory)) {
throw new ActivitiIllegalArgumentException("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() {
return new EntityManagerSessionImpl(entityManagerFactory, handleTransactions, closeEntityManager);
}
public EntityManagerFactory getEntityManagerFactory() {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a jakarta.persistence.EntityManagerFactory instance (e.g. Spring's LocalContainerEntityManagerFactoryBean's getObject())
- Upgrade/downgrade dependencies so all JPA classes come from the jakarta.persistence namespace, not javax.persistence
- Replace direct Hibernate SessionFactory usage with the JPA EntityManagerFactory facade
- Check import statements: jakarta.persistence.EntityManagerFactory, not javax.persistence
Example fix
// before import javax.persistence.EntityManagerFactory; // wrong namespace processEngineConfiguration.setJpaEntityManagerFactory(javaxEmf); // after import jakarta.persistence.EntityManagerFactory; processEngineConfiguration.setJpaEntityManagerFactory(jakartaEmf);
Defensive patterns
Strategy: type-guard
Validate before calling
// check the exact type before constructing
if (!(obj instanceof jakarta.persistence.EntityManagerFactory)) {
throw new IllegalStateException("expected jakarta.persistence.EntityManagerFactory, got " + obj.getClass().getName());
} Type guard
boolean isJakartaEmf(Object o) {
return o instanceof jakarta.persistence.EntityManagerFactory;
} Try / catch
try {
processEngineConfiguration.setJpaEntityManagerFactory(emf);
} catch (ActivitiIllegalArgumentException e) {
logger.error("wrong EntityManagerFactory type: " + emf.getClass().getName(), e);
throw e;
} Prevention
- Use jakarta.persistence imports consistently (Jakarta EE 9+)
- Avoid mixing javax and jakarta JPA dependencies on the classpath
- Pass the JPA EntityManagerFactory, not a Hibernate SessionFactory
- Pin one JPA provider version in dependency management
When it happens
Trigger: new EntityManagerSessionFactory(someObject, ...) where someObject is non-null but not an instance of jakarta.persistence.EntityManagerFactory — e.g. javax.persistence.EntityManagerFactory from a pre-Jakarta JPA provider, or a raw Hibernate SessionFactory.
Common situations: Migrating from Java EE javax.* to Jakarta EE 9+ namespaces with mixed dependency versions; passing a Hibernate ORM SessionFactory instead of a JPA EntityManagerFactory; wrong bean injected by type confusion.
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 must implement 'jakarta.persistence.Ent
- Value is not a list of JPA entities:
- Value is not a list of JPA entities: " + value
- Object is not a JPA Entity: class='${value.getClass()}', ${v
- Initiator header '${processInitiatorHeaderName}': Value must
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f50da76c6ea05a90.
Report an issue: GitHub.