flowable/flowable-engine · error · FlowableIllegalArgumentException
Object is not a JPA Entity: class='${class}', ${value}
Error message
Object is not a JPA Entity: class='${class}', ${value} What it means
After resolving EntityMetaData for the value's class, getJPAClassString verifies the class is actually a JPA entity (per Flowable's entity scanner). If not, it throws FlowableIllegalArgumentException reporting the class and value.
Source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java:74
// Class not present in meta-data map, create metaData for it and add
metaData = scanClass(clazz);
classMetaDatamap.put(clazz.getName(), metaData);
}
return metaData;
}
private EntityMetaData scanClass(Class<?> clazz) {
return enitityScanner.scanClass(clazz);
}
public String getJPAClassString(Object value) {
if (value == null) {
throw new FlowableIllegalArgumentException("null value cannot be saved");
}
EntityMetaData metaData = getEntityMetaData(value.getClass());
if (!metaData.isJPAEntity()) {
throw new FlowableIllegalArgumentException("Object is not a JPA Entity: class='" + value.getClass() + "', " + value);
}
// Extract the class from the Entity instance
return metaData.getEntityClass().getName();
}
public String getJPAIdString(Object value) {
EntityMetaData metaData = getEntityMetaData(value.getClass());
if (!metaData.isJPAEntity()) {
throw new FlowableIllegalArgumentException("Object is not a JPA Entity: class='" + value.getClass() + "', " + value);
}
Object idValue = getIdValue(value, metaData);
return getIdString(idValue);
}
public Object getIdValue(Object value, EntityMetaData metaData) {
try {
if (metaData.getIdMethod() != null) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Annotate the class with @Entity and register it in persistence.xml (or the scanned persistence unit)
- Verify jpaPersistenceUnitName/jpaEntityManagerFactory points at the unit containing the entity
- Confirm the class name and classloader (no duplicate classes across JARs confusing the scanner)
- Use a plain serializable variable type for non-entity objects instead of JPA types
Example fix
// before
public class CustomerDto { ... } // not an entity
engineConfig.setJpaEntityManagerFactory(emfFor("other-pu"));
// after
@Entity
public class Customer { ... } // registered in the configured persistence unit
engineConfig.setJpaPersistenceUnitName("correct-pu"); Defensive patterns
Strategy: type-guard
Validate before calling
boolean isRegisteredEntity(Object v) {
return v != null && v.getClass().isAnnotationPresent(jakarta.persistence.Entity.class);
} Type guard
boolean isJpaEntity(Object v) { return v != null && v.getClass().isAnnotationPresent(jakarta.persistence.Entity.class); } Try / catch
try { runtimeService.setVariable(executionId, "customer", obj); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().startsWith("Object is not a JPA Entity")) { throw new IllegalArgumentException("Register " + obj.getClass() + " in the scanned persistence unit"); } throw e; } Prevention
- Annotate classes with @Entity and list them in the persistence unit Flowable scans
- Keep jpaPersistenceUnitName aligned with the unit holding your entities
- Don't store DTOs through JPA variable types — use serializable variables for non-entities
When it happens
Trigger: Storing a variable whose class was not scanned as an @Entity — plain POJOs, non-entity classes, or entities from a persistence unit Flowable doesn't know — reaches the isJPAEntity check and fails.
Common situations: Entity class missing @Entity or not listed in persistence.xml; JPA entity scanner configured with a wrong package/persistence unit; using flowable's JPA variable types for non-JPA domain objects; multiple persistence units where the engine scans only one.
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
- Cannot set JPA variable:
- no org.flowable.app.engine.AppEngine defined in the applicat
- transactionManager is required property for SpringAppEngineC
- Could not find an implementation of the org.flowable.cdi.spi
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e11e6ded84d51052.
Report an issue: GitHub.