{"record":{"id":"4b2e2fec1e5e39de","repo":"hibernate/hibernate-orm","slug":"columndefault-may-only-be-applied-to-single-col","errorCode":null,"errorMessage":"'@ColumnDefault' may only be applied to single-column mappings but '${name}' maps to ${length} columns","messagePattern":"'@ColumnDefault' may only be applied to single-column mappings but '(.+?)' maps to (.+?) columns","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java","lineNumber":927,"sourceCode":"\n\tprivate static String getColumnName(Database database, jakarta.persistence.Column column) {\n\t\tfinal String name = column.name();\n\t\treturn name.isBlank()\n\t\t\t\t? null\n\t\t\t\t: database.getJdbcEnvironment().getIdentifierHelper().toIdentifier( name ).render();\n\t}\n\n\tvoid applyColumnDefault(PropertyData inferredData, int length) {\n\t\tfinal var memberDetails = inferredData.getAttributeMember();\n\t\tif ( memberDetails != null ) {\n\t\t\tfinal var columnDefault = getOverridableAnnotation(\n\t\t\t\t\tmemberDetails,\n\t\t\t\t\tColumnDefault.class,\n\t\t\t\t\tgetBuildingContext()\n\t\t\t);\n\t\t\tif ( columnDefault != null ) {\n\t\t\t\tif ( length != 1 ) {\n\t\t\t\t\tthrow new AnnotationException( \"'@ColumnDefault' may only be applied to single-column mappings but '\"\n\t\t\t\t\t\t\t+ memberDetails.getName() + \"' maps to \" + length + \" columns\" );\n\t\t\t\t}\n\t\t\t\tsetDefaultValue( columnDefault.value() );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tBOOT_LOGGER.couldNotPerformColumnDefaultLookup();\n\t\t}\n\t}\n\n\tvoid applyGeneratedAs(PropertyData inferredData, int length) {\n\t\tfinal var memberDetails = inferredData.getAttributeMember();\n\t\tif ( memberDetails != null ) {\n\t\t\tfinal var generatedColumn = getOverridableAnnotation(\n\t\t\t\t\tmemberDetails,\n\t\t\t\t\tGeneratedColumn.class,\n\t\t\t\t\tgetBuildingContext()\n\t\t\t);","sourceCodeStart":909,"sourceCodeEnd":945,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java#L909-L945","documentation":"AnnotatedColumn.applyColumnDefault applies the DDL default from @ColumnDefault when binding a column. The annotation describes a DEFAULT clause for exactly one column, so when the annotated property maps to a different number of columns than 1 (a composite/embedded or multi-column basic type), binding fails with this AnnotationException naming the member and the actual column count.","triggerScenarios":"Placing @ColumnDefault on a property whose mapping spans multiple columns - an @Embedded attribute, a multi-column user type (@Type with @Columns, e.g. monetary amount+currency), or an aggregate - during metadata binding.","commonSituations":"Adding @ColumnDefault to an embedded attribute for convenience; annotating composite custom types ported from single-column predecessors; bulk-adding default annotations with tooling that ignores column counts.","solutions":["Move @ColumnDefault off the multi-column property","Apply the default to the specific single-column leaf (target the embeddable field that maps one column)","If a default is needed on several columns, define them per-column inside the embeddable or via column definition SQL"],"exampleFix":"// before: default on a multi-column embedded property\n@Embeddable\npublic class Money { BigDecimal amount; String currency; }   // 2 columns\n\n@Entity\npublic class Payment {\n    @ColumnDefault(\"0\")        // 1 default for 2 columns -> error\n    @Embedded\n    private Money money;\n}\n\n// after: default on the single-column leaf\n@Embeddable\npublic class Money {\n    @ColumnDefault(\"0\")\n    private BigDecimal amount;\n    private String currency;\n}","handlingStrategy":"validation","validationCode":"// Before boot: @ColumnDefault must not sit on embedded/multi-column attributes\nstatic boolean columnDefaultsAreSingleColumn(Class<?> entity) {\n    for (Field f : entity.getDeclaredFields()) {\n        if (f.isAnnotationPresent(ColumnDefault.class)\n                && (f.isAnnotationPresent(Embedded.class) || f.isAnnotationPresent(Columns.class))) {\n            return false;\n        }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    final SessionFactory sf = new MetadataSources(standardServiceRegistry)\n            .addAnnotatedClass(MyEntity.class)\n            .buildMetadata()\n            .buildSessionFactory();\n} catch (AnnotationException | MappingException e) {\n    throw new IllegalStateException(\"Invalid ORM mapping, aborting startup: \" + e.getMessage(), e);\n}","preventionTips":["Treat @ColumnDefault as a leaf-level, single-column annotation","Put defaults inside the embeddable on the exact field they affect","Smoke-test mappings in CI so misplaced annotations fail early"],"tags":["hibernate","column-default","embeddable","multi-column","annotation","mapping"],"backgroundTag":"single-column-annotation-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}