{"record":{"id":"d00376ac73648274","repo":"hibernate/hibernate-orm","slug":"generatedcolumn-may-only-be-applied-to-single-c","errorCode":null,"errorMessage":"'@GeneratedColumn' may only be applied to single-column mappings but '${name}' maps to ${length} columns","messagePattern":"'@GeneratedColumn' 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":948,"sourceCode":"\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);\n\t\t\tif ( generatedColumn != null ) {\n\t\t\t\tif (length!=1) {\n\t\t\t\t\tthrow new AnnotationException(\"'@GeneratedColumn' 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\tsetGeneratedAs( generatedColumn.value() );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tBOOT_LOGGER.couldNotPerformGeneratedColumnLookup();\n\t\t}\n}\n\n\tprivate void applyColumnCheckConstraint(jakarta.persistence.Column column) {\n\t\tapplyCheckConstraints( column.check() );\n\t}\n\n\tvoid applyCheckConstraints(jakarta.persistence.CheckConstraint[] checkConstraintAnnotationUsages) {\n\t\tif ( isNotEmpty( checkConstraintAnnotationUsages ) ) {\n\t\t\tfor ( var checkConstraintAnnotationUsage : checkConstraintAnnotationUsages ) {\n\t\t\t\taddCheckConstraint(","sourceCodeStart":930,"sourceCodeEnd":966,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java#L930-L966","documentation":"AnnotatedColumn.applyGeneratedAs reads @GeneratedColumn (Hibernate annotation that renders a GENERATED ALWAYS AS ... DDL clause) when binding a column. A generated-column clause targets exactly one physical column, so applying it to a property that maps a number of columns other than 1 throws this AnnotationException with the member name and column count.","triggerScenarios":"Placing @GeneratedColumn on an @Embedded attribute, a composite user type, or any multi-column mapping during metadata binding.","commonSituations":"Adding @GeneratedColumn to embedded/aggregate attributes; migrating single-column types to composite ones (e.g. money split into amount+currency) while keeping the annotation; copy-paste of generated-column setup onto the wrong field.","solutions":["Remove @GeneratedColumn from the multi-column property","Apply it to the single mapped column that is actually generated (the specific field inside the embeddable or the one-column basic)","If generation must involve several columns, express it in the column definition or a migration script instead"],"exampleFix":"// before: generated column on an embedded (multi-column) attribute\n@Entity\npublic class Invoice {\n    @GeneratedColumn(\"concat(no, '-', year)\")   // spans 2 columns -> error\n    @Embedded\n    private InvoiceNo no;\n}\n\n// after: annotate only the single-column field that is generated\n@Embeddable\npublic class InvoiceNo {\n    @GeneratedColumn(\"concat(prefix, seq)\")\n    private String display;     // maps exactly one column\n    private String prefix;\n    private long seq;\n}","handlingStrategy":"validation","validationCode":"// Before boot: @GeneratedColumn must not sit on embedded/multi-column attributes\nstatic boolean generatedColumnsAreSingleColumn(Class<?> entity) {\n    for (Field f : entity.getDeclaredFields()) {\n        if (f.isAnnotationPresent(GeneratedColumn.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":["Remember @GeneratedColumn writes DDL for one column only","Keep generated columns on simple basic attributes","Review annotations whenever a type changes from single- to multi-column"],"tags":["hibernate","generated-column","embeddable","multi-column","annotation","mapping","ddl"],"backgroundTag":"single-column-annotation-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}