flowable/flowable-engine · error · FlowableIllegalArgumentException
Value of primary key for JPA-Entity cannot be null
Error message
Value of primary key for JPA-Entity cannot be null
What it means
getIdString serializes a JPA entity's primary key value to a string for storage in a Flowable variable row. If the @Id value on the entity instance is null, Flowable cannot persist or look up the variable reference, so it throws immediately.
Source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java:168
return Character.valueOf(string.charAt(0));
} else if (type == java.util.Date.class) {
return new java.util.Date(Long.parseLong(string));
} else if (type == java.sql.Date.class) {
return new java.sql.Date(Long.parseLong(string));
} else if (type == BigDecimal.class) {
return new BigDecimal(string);
} else if (type == BigInteger.class) {
return new BigInteger(string);
} else if (type == UUID.class) {
return UUID.fromString(string);
} else {
throw new FlowableIllegalArgumentException("Unsupported Primary key type for JPA-Entity: " + type.getName());
}
}
public String getIdString(Object value) {
if (value == null) {
throw new FlowableIllegalArgumentException("Value of primary key for JPA-Entity cannot be null");
}
// Only java.util.Date requires custom handling,
// the other types can just use toString()
if (value instanceof java.util.Date) {
return String.valueOf(((java.util.Date) value).getTime());
} else if (value instanceof Long || value instanceof String || value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Float || value instanceof Double
|| value instanceof Character || value instanceof BigDecimal || value instanceof BigInteger || value instanceof UUID) {
return value.toString();
} else {
throw new FlowableIllegalArgumentException("Unsupported Primary key type for JPA-Entity: " + value.getClass().getName());
}
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Persist the entity and flush the EntityManager before assigning it to the Flowable variable, so the id generator has populated the @Id.
- Confirm the entity was saved in the same command context whose EntityManagerSession Flowable uses (JPAEntityVariableType.flushes pending changes on setValue).
- Add a null check on the entity's id in your own code before setting the variable and fail fast with a clearer message.
- For manually assigned ids, ensure application code always sets the id before the entity is used as a variable value.
Example fix
// before processEngine.getTaskService().setVariable(taskId, "entity", new Customer()); // id null // after Customer c = new Customer(); entityManager.persist(c); entityManager.flush(); // id now assigned processEngine.getTaskService().setVariable(taskId, "entity", c);
Defensive patterns
Strategy: validation
Validate before calling
Object id = entityManager.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(entity);
if (id == null) throw new IllegalStateException("Entity id not assigned; persist+flush before storing as Flowable variable"); Type guard
boolean hasId(Object e) { return emf.getPersistenceUnitUtil().getIdentifier(e) != null; } Try / catch
try { taskService.setVariable(taskId, "entity", entity); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().contains("cannot be null")) { em.flush(); taskService.setVariable(taskId, "entity", entity); } else throw e; } Prevention
- Always persist and flush the entity before putting it into a Flowable variable.
- Rely on Flowable's own flush of the EntityManagerSession, and keep entity writes in the same command context.
- Add a debug assertion checking PersistenceUnitUtil.getIdentifier(entity) != null in dev/test.
When it happens
Trigger: Calling getJPAIdString on an entity instance whose @Id field/getter returns null — typically a newly created (not yet persisted/flushed) entity, or an entity whose id was never assigned.
Common situations: Passing a `new SomeEntity()` to Flowable's setValue before save; missing EntityManager flush so the @GeneratedValue id is not yet populated; entities saved with a different EntityManager than the one Flowable flushed.
Related errors
- Unsupported Primary key type for JPA-Entity: ${type}
- Script content is null or evaluated to null for taskListener
- byte array for resource '${resourceName}' is null
- error.identifier.method.notfound
- Could not resolve key for: ${eventDefinitionKey} in ${execut
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/cc1508b614db44b0.
Report an issue: GitHub.