{"record":{"id":"015dba83562ce272","repo":"hibernate/hibernate-orm","slug":"property-path-overrides-mapping-specified-usi","errorCode":null,"errorMessage":"Property '${path}' overrides mapping specified using '@JoinColumnOrFormula'","messagePattern":"Property '(.+?)' overrides mapping specified using '@JoinColumnOrFormula'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedJoinColumn.java","lineNumber":84,"sourceCode":"\t/**\n\t * @return true if the {@code @JoinColumn} annotation did not specify the\n\t *         {@link JoinColumn#referencedColumnName() referencedColumnName}.\n\t */\n\tpublic boolean isReferenceImplicit() {\n\t\treturn isEmpty( referencedColumn );\n\t}\n\n\tstatic AnnotatedJoinColumn buildJoinColumn(\n\t\t\tJoinColumn joinColumn,\n\t\t\tString mappedBy,\n\t\t\tAnnotatedJoinColumns parent,\n\t\t\tPropertyHolder propertyHolder,\n\t\t\tPropertyData inferredData) {\n\t\tfinal String path = qualify( propertyHolder.getPath(), inferredData.getPropertyName() );\n\t\tfinal var overrides = propertyHolder.getOverriddenJoinColumn( path );\n\t\tif ( overrides != null ) {\n\t\t\t//TODO: relax this restriction\n\t\t\tthrow new AnnotationException( \"Property '\" + path\n\t\t\t\t\t+ \"' overrides mapping specified using '@JoinColumnOrFormula'\" );\n\t\t}\n\t\treturn buildJoinColumn( joinColumn, mappedBy, parent, propertyHolder, inferredData, \"\" );\n\t}\n\n\tpublic static AnnotatedJoinColumn buildJoinFormula(\n\t\t\tJoinFormula joinFormula,\n\t\t\tAnnotatedJoinColumns parent) {\n\t\tfinal var formulaColumn = new AnnotatedJoinColumn();\n\t\tformulaColumn.setFormula( joinFormula.value() );\n\t\tformulaColumn.setReferencedColumn( joinFormula.referencedColumnName() );\n//\t\tformulaColumn.setContext( buildingContext );\n//\t\tformulaColumn.setPropertyHolder( propertyHolder );\n//\t\tformulaColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );\n//\t\tformulaColumn.setJoins( joins );\n\t\tformulaColumn.setParent( parent );\n\t\tformulaColumn.bind();\n\t\treturn formulaColumn;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedJoinColumn.java#L66-L102","documentation":"The property is part of an embedded or inherited mapping that was originally declared with '@JoinColumnOrFormula' (a mix of a real join column and a formula). Something else — typically an '@AssociationOverride' (annotation or XML) — then tries to re-map that same property path with plain join columns. Hibernate cannot override a formula-based association mapping, so it rejects the override outright (the source even carries a 'TODO: relax this restriction' note).","triggerScenarios":"An @Embedded/@EmbeddedId or @MappedSuperclass declares an association with @JoinColumnOrFormula(...), and the embedding entity applies @AssociationOverride(name=\"<embeddable>.<assoc>\", joinColumns=@JoinColumn(...)) or an XML <association-override> for that path; propertyHolder.getOverriddenJoinColumn(path) then returns a non-null override.","commonSituations":"Reusing a shared embeddable (e.g. a generic audit or reference component) that uses @JoinColumnOrFormula, then overriding it in a concrete entity; migrating mappings to XML and back where overrides are reapplied mechanically; Envers-style or custom embeddables with formula-based references.","solutions":["Remove the @AssociationOverride (or XML <association-override>) that targets the property path shown in the message.","If the override is required, change the original mapping from @JoinColumnOrFormula to plain @JoinColumn(s) so the override can apply.","Instead of overriding, define the association directly on the concrete entity with the desired @JoinColumn mapping."],"exampleFix":"// before\n@Embeddable\nclass Ref {\n    @ManyToOne\n    @JoinColumnOrFormula(column = @JoinColumn(name = \"item_id\"))\n    private Item item;\n}\n\n@Entity\n@AssociationOverride(name = \"ref.item\", joinColumns = @JoinColumn(name = \"prod_item_id\")) // -> error\nclass Product { private Ref ref; }\n\n// after\n@Entity\nclass Product {\n    @Embedded\n    private Ref ref; // no override; or remap Ref.item with plain @JoinColumn\n}","handlingStrategy":"validation","validationCode":"// Fail fast when an override targets a formula-based association\n// (inspect source embeddables before SessionFactory construction)\nif (hasAssociationOverride(targetClass, \"ref.item\")\n        && usesJoinColumnOrFormula(embeddableClass, \"item\")) {\n    throw new IllegalStateException(\n        \"Cannot @AssociationOverride a @JoinColumnOrFormula mapping: ref.item\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Metadata md = new MetadataSources(registry).addAnnotatedClass(Product.class)\n        .buildMetadata();\n} catch (AnnotationException e) {\n    // message shows the overridden path; remove the override or change the base mapping\n    throw newConfigurationException(\"Unsupported association override\", e);\n}","preventionTips":["Treat @JoinColumnOrFormula mappings as non-overridable; document them in the embeddable's Javadoc.","Prefer plain @JoinColumn in shared embeddables so subclasses can override them.","When adding @AssociationOverride, re-run a mapping test for every entity that embeds the component."],"tags":["hibernate","jpa","association-override","join-formula","orm-mapping"],"backgroundTag":"association-override-error","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}