{"record":{"id":"71f1d67990c95064","repo":"flowable/flowable-engine","slug":"illegal-argument-exception-when-getting-value-from","errorCode":null,"errorMessage":"Illegal argument exception when getting value from id method/field on JPAEntity","messagePattern":"Illegal argument exception when getting value from id method/field on JPAEntity","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java","lineNumber":98,"sourceCode":"\n    public String getJPAIdString(Object value) {\n        EntityMetaData metaData = getEntityMetaData(value.getClass());\n        if (!metaData.isJPAEntity()) {\n            throw new FlowableIllegalArgumentException(\"Object is not a JPA Entity: class='\" + value.getClass() + \"', \" + value);\n        }\n        Object idValue = getIdValue(value, metaData);\n        return getIdString(idValue);\n    }\n\n    public Object getIdValue(Object value, EntityMetaData metaData) {\n        try {\n            if (metaData.getIdMethod() != null) {\n                return metaData.getIdMethod().invoke(value);\n            } else if (metaData.getIdField() != null) {\n                return metaData.getIdField().get(value);\n            }\n        } catch (IllegalArgumentException iae) {\n            throw new FlowableException(\"Illegal argument exception when getting value from id method/field on JPAEntity\", iae);\n        } catch (IllegalAccessException iae) {\n            throw new FlowableException(\"Cannot access id method/field for JPA Entity\", iae);\n        } catch (InvocationTargetException ite) {\n            throw new FlowableException(\"Exception occurred while getting value from id field/method on JPAEntity: \" + ite.getCause().getMessage(), ite.getCause());\n        }\n\n        // Fall trough when no method and field is set\n        throw new FlowableException(\"Cannot get id from JPA Entity, no id method/field set\");\n    }\n\n    public Object getJPAEntity(String className, String idString) {\n        Class<?> entityClass = null;\n        entityClass = ReflectUtil.loadClass(className);\n\n        EntityMetaData metaData = getEntityMetaData(entityClass);\n\n        // Create primary key of right type\n        Object primaryKey = createId(metaData, idString);","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java#L80-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nentityManager.find(Order.class, id); // proxy instance of subclass stored\nvariableScope.setVariable(\"order\", order.getLazyProxy());\n// after\nOrder order = entityManager.find(Order.class, id); // concrete instance\nvariableScope.setVariable(\"order\", order);","handlingStrategy":"type-guard","validationCode":"// before storing/reading a JPA variable\nif (value == null || !expectedEntityClass.isInstance(value)) {\n    throw new IllegalArgumentException(\"Value is not an instance of \" + expectedEntityClass.getName());\n}","typeGuard":"boolean isJpaEntityOfType(Object v, Class<?> entityType) {\n    return v != null && entityType.isAssignableFrom(v.getClass()) && !v.getClass().getName().contains(\"$Proxy\");\n}","tryCatchPattern":"try {\n    Object id = variableScope.getVariable(\"entityVar\");\n} catch (org.flowable.common.engine.api.FlowableException e) {\n    if (e.getCause() instanceof IllegalArgumentException) {\n        // re-fetch or unwrap proxy, then retry\n    }\n}","preventionTips":["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."],"tags":["jpa","reflection","illegal-argument","variables"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}