hibernate/hibernate-orm · error · AnnotationException
'@GeneratedColumn' may only be applied to single-column mapp
Error message
'@GeneratedColumn' may only be applied to single-column mappings but '${name}' maps to ${length} columns What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java:948
setDefaultValue( columnDefault.value() );
}
}
else {
BOOT_LOGGER.couldNotPerformColumnDefaultLookup();
}
}
void applyGeneratedAs(PropertyData inferredData, int length) {
final var memberDetails = inferredData.getAttributeMember();
if ( memberDetails != null ) {
final var generatedColumn = getOverridableAnnotation(
memberDetails,
GeneratedColumn.class,
getBuildingContext()
);
if ( generatedColumn != null ) {
if (length!=1) {
throw new AnnotationException("'@GeneratedColumn' may only be applied to single-column mappings but '"
+ memberDetails.getName() + "' maps to " + length + " columns" );
}
setGeneratedAs( generatedColumn.value() );
}
}
else {
BOOT_LOGGER.couldNotPerformGeneratedColumnLookup();
}
}
private void applyColumnCheckConstraint(jakarta.persistence.Column column) {
applyCheckConstraints( column.check() );
}
void applyCheckConstraints(jakarta.persistence.CheckConstraint[] checkConstraintAnnotationUsages) {
if ( isNotEmpty( checkConstraintAnnotationUsages ) ) {
for ( var checkConstraintAnnotationUsage : checkConstraintAnnotationUsages ) {
addCheckConstraint(View on GitHub (pinned to fad1729dce)
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
Example fix
// before: generated column on an embedded (multi-column) attribute
@Entity
public class Invoice {
@GeneratedColumn("concat(no, '-', year)") // spans 2 columns -> error
@Embedded
private InvoiceNo no;
}
// after: annotate only the single-column field that is generated
@Embeddable
public class InvoiceNo {
@GeneratedColumn("concat(prefix, seq)")
private String display; // maps exactly one column
private String prefix;
private long seq;
} Defensive patterns
Strategy: validation
Validate before calling
// Before boot: @GeneratedColumn must not sit on embedded/multi-column attributes
static boolean generatedColumnsAreSingleColumn(Class<?> entity) {
for (Field f : entity.getDeclaredFields()) {
if (f.isAnnotationPresent(GeneratedColumn.class)
&& (f.isAnnotationPresent(Embedded.class) || f.isAnnotationPresent(Columns.class))) {
return false;
}
}
return true;
} Try / catch
try {
final SessionFactory sf = new MetadataSources(standardServiceRegistry)
.addAnnotatedClass(MyEntity.class)
.buildMetadata()
.buildSessionFactory();
} catch (AnnotationException | MappingException e) {
throw new IllegalStateException("Invalid ORM mapping, aborting startup: " + e.getMessage(), e);
} Prevention
- 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
When it happens
Trigger: Placing @GeneratedColumn on an @Embedded attribute, a composite user type, or any multi-column mapping during metadata binding.
Common situations: 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.
Related errors
- '@Check' may only be applied to single-column mappings but '
- '@ColumnDefault' may only be applied to single-column mappin
- Property '${path}' specifies ${columnCount} '@AttributeOverr
- Multiple check constraints not supported for aggregate colum
- '@AttributeAccessor' annotation must specify a 'strategy'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/d00376ac73648274.
Report an issue: GitHub.