{"record":{"id":"b8fe737aabda6120","repo":"hibernate/hibernate-orm","slug":"identifier-property-getpath-holder-data","errorCode":null,"errorMessage":"Identifier property '\" + getPath( holder, data ) + \"' cannot map to a '@Formula'","messagePattern":"Identifier property '\" \\+ getPath\\( holder, data \\) \\+ \"' cannot map to a '@Formula'","errorType":"exception","errorClass":"CannotForceNonNullableException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":1371,"sourceCode":"\t\t\tNullability nullability,\n\t\t\tMemberDetails property,\n\t\t\tAnnotatedColumns columns) {\n\t\tif ( shouldForceNotNull( nullability, isExplicitlyOptional( property ) ) ) {\n\t\t\tforceColumnsNotNull( propertyHolder, inferredData, columns );\n\t\t}\n\n\t\tsetLazy( isLazy( property ) );\n\t\tsetColumns( columns );\n\t\tmakePropertyValueAndBind();\n\t}\n\n\tprivate void forceColumnsNotNull(\n\t\t\tPropertyHolder holder,\n\t\t\tPropertyData data,\n\t\t\tAnnotatedColumns columns) {\n\t\tfor ( AnnotatedColumn column : columns.getColumns() ) {\n\t\t\tif ( isId() && column.isFormula() ) {\n\t\t\t\tthrow new CannotForceNonNullableException( \"Identifier property '\"\n\t\t\t\t\t\t+ getPath( holder, data ) + \"' cannot map to a '@Formula'\" );\n\t\t\t}\n\t\t\tcolumn.forceNotNull();\n\t\t}\n\t}\n\n\tprivate boolean shouldForceNotNull(Nullability nullability, boolean optional) {\n\t\treturn isId()\n\t\t\t|| !optional && nullability != Nullability.FORCED_NULL;\n\t}\n\n\t/**\n\t * Should this property be considered optional, without considering\n\t * whether it is primitive?\n\t *\n\t * @apiNote Poorly named to a degree.\n\t *          The intention is really whether non-optional is explicit\n\t */","sourceCodeStart":1353,"sourceCodeEnd":1389,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L1353-L1389","documentation":"Thrown when an identifier property is mapped to a @Formula instead of a real column. During binding, PropertyBinder.forceColumnsNotNull forces every column backing an id to NOT NULL; a formula is a read-only SQL expression with no column, so CannotForceNonNullableException (an AnnotationException subclass) aborts bootstrap. It only fires when isId() is true for the property being bound.","triggerScenarios":"Entity declares @Id on a field/getter that also carries @Formula(\"...\"), or an @EmbeddedId embeddable whose member uses @Formula. Raised while Hibernate binds the id property and iterates its AnnotatedColumns, never at runtime.","commonSituations":"Trying to use a computed/derived SQL expression as the primary key; aliasing real columns with @Formula and accidentally applying it to the id; mapping an entity to a database view and marking a view column formula-based; copying @Formula conventions from read-only attributes onto identifiers.","solutions":["Remove @Formula from the identifier attribute and map it to a real column with @Column(name = ...).","If the key value is computed in SQL, generate it in the database (generated column, trigger, or default) and map the resulting column normally.","If the id should be synthetic, use @Id @GeneratedValue with a proper id column instead of deriving it from an expression.","Restructure view-backed entities so the id maps to a plain (non-formula) column of the view."],"exampleFix":"// before\n@Id\n@Formula(\"regexp_replace(code, 'X', '')\")\nprivate Long id;\n\n// after\n@Id\n@GeneratedValue\n@Column(name = \"id\", nullable = false)\nprivate Long id;","handlingStrategy":"validation","validationCode":"// CI guard: boot the mapping cheaply and fail fast on bad id formulas\nMetadata metadata = new MetadataSources(new StandardServiceRegistryBuilder().build())\n        .addAnnotatedClass(Order.class)\n        .buildMetadata(); // throws CannotForceNonNullableException here, not in production","typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = metadata.buildSessionFactory();\n} catch (AnnotationException e) { // CannotForceNonNullableException extends AnnotationException\n    throw new IllegalStateException(\"Mapping rejected: \" + e.getMessage(), e);\n}","preventionTips":["Never combine @Id or @EmbeddedId members with @Formula.","Keep a bootstrap smoke test that builds Metadata for every mapped class in CI.","Review any entity mapped to views: ids must reference real columns."],"tags":["hibernate","orm","mapping","identifier","formula","boot"],"backgroundTag":"invalid-entity-mapping","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}