flowable/flowable-engine · error · FlowableException
Illegal argument exception when getting value from id method
Error message
Illegal argument exception when getting value from id method/field on JPAEntity
What it means
Flowable's JPA variable type reads the primary key of a JPA entity variable via reflection, invoking the configured @Id getter method or reading the @Id field. A java.lang.IllegalArgumentException from Method.invoke or Field.get means the object being passed is not an instance of the class that declares that id method/field, or the value cannot be converted to the declared parameter/return type. Flowable wraps it in a FlowableException with this message.
Source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java:98
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) {
return metaData.getIdMethod().invoke(value);
} else if (metaData.getIdField() != null) {
return metaData.getIdField().get(value);
}
} catch (IllegalArgumentException iae) {
throw new FlowableException("Illegal argument exception when getting value from id method/field on JPAEntity", iae);
} catch (IllegalAccessException iae) {
throw new FlowableException("Cannot access id method/field for JPA Entity", iae);
} catch (InvocationTargetException ite) {
throw new FlowableException("Exception occurred while getting value from id field/method on JPAEntity: " + ite.getCause().getMessage(), ite.getCause());
}
// Fall trough when no method and field is set
throw new FlowableException("Cannot get id from JPA Entity, no id method/field set");
}
public Object getJPAEntity(String className, String idString) {
Class<?> entityClass = null;
entityClass = ReflectUtil.loadClass(className);
EntityMetaData metaData = getEntityMetaData(entityClass);
// Create primary key of right type
Object primaryKey = createId(metaData, idString);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Verify the object stored as a JPA variable is an actual instance of the entity class listed in configuration <jpa-persistence-unit> / jpaEntityClassMappings (check value.getClass() vs metaData target class).
- Ensure the @Id accessor has no unexpected parameter types and the entity class is not shadowed by duplicate class versions on the classpath.
- Disable or unwrap lazy proxies before persisting the variable, or configure the id method on the concrete entity class.
- Call Flowable's refresh on EntityMetaData (scanEntities) after changing entity classes so cached metadata matches runtime classes.
Example fix
// before
entityManager.find(Order.class, id); // proxy instance of subclass stored
variableScope.setVariable("order", order.getLazyProxy());
// after
Order order = entityManager.find(Order.class, id); // concrete instance
variableScope.setVariable("order", order); Defensive patterns
Strategy: type-guard
Validate before calling
// before storing/reading a JPA variable
if (value == null || !expectedEntityClass.isInstance(value)) {
throw new IllegalArgumentException("Value is not an instance of " + expectedEntityClass.getName());
} Type guard
boolean isJpaEntityOfType(Object v, Class<?> entityType) {
return v != null && entityType.isAssignableFrom(v.getClass()) && !v.getClass().getName().contains("$Proxy");
} Try / catch
try {
Object id = variableScope.getVariable("entityVar");
} catch (org.flowable.common.engine.api.FlowableException e) {
if (e.getCause() instanceof IllegalArgumentException) {
// re-fetch or unwrap proxy, then retry
}
} Prevention
- Store only concrete entity instances, not proxies or subclasses, in JPA variables.
- Keep the entity class list in the engine configuration in sync with runtime classes.
- Unwrap Hibernate proxies before setting the variable.
- Re-scan entity metadata after entity class changes.
When it happens
Trigger: Calling idValue()/getIdValue() with a 'value' object that is not an instance of the entity class the EntityMetaData was built from (e.g. a proxy, a different entity type, or null-typed mismatch), or a getter whose declared parameter/return type is incompatible with the supplied argument during Method.invoke.
Common situations: Storing a variable whose runtime type differs from the entity class registered in the VariableServiceConfiguration JPA entity list; using Hibernate/javassist lazy-loading proxies passed to the reflective accessor; mismatched entity class after refactoring; storing a JPA variable when jpaHandleTransaction/persistence unit was misconfigured so the object is not the real entity.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot access id method/field for JPA Entity
- Cannot set JPA variable:
- Value is not a list of JPA entities:
- Exception occurred while getting value from id field/method
- Entity does not exist: ${entityClass} - ${primaryKey}
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/71f1d67990c95064.
Report an issue: GitHub.