{"record":{"id":"4168e3427b33ab56","repo":"flowable/flowable-engine","slug":"cannot-access-id-method-field-for-jpa-entity","errorCode":null,"errorMessage":"Cannot access id method/field for JPA Entity","messagePattern":"Cannot access id method/field for JPA Entity","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":100,"sourceCode":"        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);\n        return findEntity(entityClass, primaryKey);\n    }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java#L82-L118","documentation":"When reading a JPA entity variable's id via reflection, Field.get threw java.lang.IllegalAccessException because the @Id field is not accessible (private/protected without setAccessible succeeding, e.g. under a security manager or module restrictions). Flowable rethrows it as this FlowableException.","triggerScenarios":"getIdValue() falls into the metaData.getIdField().get(value) branch and the field is private/package-private and setAccessible(true) was not applied or was denied; entity class in a Java module that does not open the package to Flowable.","commonSituations":"Entities with an @Id field but no getter, combined with JPMS strong encapsulation (Java 9+) or a SecurityManager; OSGi/classloader setups where setAccessible is rejected; newer JDKs restricting reflection on non-opened packages.","solutions":["Add a public getter for the @Id field so the idMethod branch is used instead of field reflection.","Ensure Flowable can setAccessible(true): open the entity package in module-info.java (opens com.myapp.entities;) or avoid SecurityManager restrictions.","Annotate the id getter rather than only the field: place @Id on the public getter.","Fall back to a JDK version/profile without module restrictions or add --add-opens for the entity package."],"exampleFix":"// before\n@Id\nprivate Long id; // private field only, no getter\n// after\n@Id\npublic Long getId() { return id; } // public getter, or add 'opens com.myapp.entities;' to module-info","handlingStrategy":"validation","validationCode":"// verify the @Id member is reflectively accessible before use\njava.lang.reflect.Field f = entity.getClass().getDeclaredField(\"id\");\nf.setAccessible(true);\nf.get(entity); // throws IllegalAccessException early if still denied","typeGuard":null,"tryCatchPattern":"try {\n    Object v = runtimeService.getVariable(executionId, \"jpaVar\");\n} catch (org.flowable.common.engine.api.FlowableException e) {\n    if (e.getMessage().contains(\"Cannot access id method/field\")) {\n        // fall back to reading the id directly from your own entity access layer\n    }\n}","preventionTips":["Always expose a public getter for the @Id field.","On JPMS, add 'opens your.entity.package;' to module-info.java.","Avoid SecurityManager policies that deny setAccessible on entity classes.","Prefer property (getter) access for @Id in entities."],"tags":["jpa","reflection","illegal-access","variables"],"backgroundTag":"permission-denied","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"}