{"record":{"id":"cc1508b614db44b0","repo":"flowable/flowable-engine","slug":"value-of-primary-key-for-jpa-entity-cannot-be-null","errorCode":null,"errorMessage":"Value of primary key for JPA-Entity cannot be null","messagePattern":"Value of primary key for JPA-Entity cannot be null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java","lineNumber":168,"sourceCode":"            return Character.valueOf(string.charAt(0));\n        } else if (type == java.util.Date.class) {\n            return new java.util.Date(Long.parseLong(string));\n        } else if (type == java.sql.Date.class) {\n            return new java.sql.Date(Long.parseLong(string));\n        } else if (type == BigDecimal.class) {\n            return new BigDecimal(string);\n        } else if (type == BigInteger.class) {\n            return new BigInteger(string);\n        } else if (type == UUID.class) {\n            return UUID.fromString(string);\n        } else {\n            throw new FlowableIllegalArgumentException(\"Unsupported Primary key type for JPA-Entity: \" + type.getName());\n        }\n    }\n\n    public String getIdString(Object value) {\n        if (value == null) {\n            throw new FlowableIllegalArgumentException(\"Value of primary key for JPA-Entity cannot be null\");\n        }\n        // Only java.util.Date requires custom handling,\n        // the other types can just use toString()\n        if (value instanceof java.util.Date) {\n            return String.valueOf(((java.util.Date) value).getTime());\n        } else if (value instanceof Long || value instanceof String || value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Float || value instanceof Double\n                || value instanceof Character || value instanceof BigDecimal || value instanceof BigInteger || value instanceof UUID) {\n            return value.toString();\n        } else {\n            throw new FlowableIllegalArgumentException(\"Unsupported Primary key type for JPA-Entity: \" + value.getClass().getName());\n        }\n    }\n}\n","sourceCodeStart":150,"sourceCodeEnd":182,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/types/JPAEntityMappings.java#L150-L182","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nprocessEngine.getTaskService().setVariable(taskId, \"entity\", new Customer()); // id null\n// after\nCustomer c = new Customer();\nentityManager.persist(c);\nentityManager.flush(); // id now assigned\nprocessEngine.getTaskService().setVariable(taskId, \"entity\", c);","handlingStrategy":"validation","validationCode":"Object id = entityManager.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(entity);\nif (id == null) throw new IllegalStateException(\"Entity id not assigned; persist+flush before storing as Flowable variable\");","typeGuard":"boolean hasId(Object e) { return emf.getPersistenceUnitUtil().getIdentifier(e) != null; }","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["jpa","primary-key","null-value","flowable"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}