hibernate/hibernate-orm · error · MappingException
CurrentTimestampGeneration requires exactly one column
Error message
CurrentTimestampGeneration requires exactly one column
What it means
Thrown at bootstrap while initializing CurrentTimestampGeneration (@CurrentTimestamp): the generator writes one value per event, so the annotated property must map to exactly one column. The notNull() initialization step enforces this (and also marks the property non-optional and the column NOT NULL). A property mapped to multiple columns fails with this MappingException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/generator/internal/CurrentTimestampGeneration.java:131
delegate = getGeneratorDelegate( annotation.source(), context.getType(), context );
eventTypes = INSERT_AND_UPDATE;
propertyType = getPropertyType( context );
version = isVersion( context );
notNull( context );
}
private static boolean isVersion(GeneratorCreationContext context) {
final var persistentClass = context.getPersistentClass();
return persistentClass != null
&& context.getProperty() == persistentClass.getVersion();
}
private static void notNull(GeneratorCreationContext context) {
final var property = context.getProperty();
property.setOptional( false );
final var columns = property.getColumns();
if ( columns.size() != 1 ) {
throw new MappingException( "CurrentTimestampGeneration requires exactly one column" );
}
columns.get( 0 ).setNullable( false );
}
private static GeneratorDelegate getGeneratorDelegate(
SourceType source,
Type type,
GeneratorCreationContext context) {
return getGeneratorDelegate( source, type.getReturnedClass(), context );
}
static GeneratorDelegate getGeneratorDelegate(
SourceType source,
Class<?> propertyType,
GeneratorCreationContext context) {
return switch (source) {
case DB -> null;
case VM -> getGeneratorDelegate( propertyType, getBaseClock( context ), getPrecision( context ) );View on GitHub (pinned to fad1729dce)
Solutions
- Map the timestamp attribute to exactly one column — drop @Columns or replace the multi-column UserType with a single-column AttributeConverter or a built-in java.time mapping
- If the DB type is exotic, write an AttributeConverter to a single supported column type instead of a multi-column mapping
- Remove @CurrentTimestamp and set the value in a @PrePersist/@PreUpdate listener, or use a DB trigger with @Generated
- If the same embeddable is reused across tables, check the member's column mapping in each host entity
Example fix
// before — @CurrentTimestamp on a 2-column mapping
@CurrentTimestamp(event = EventType.INSERT)
@Columns({@Column(name = "created_date"), @Column(name = "created_time")})
LocalDateTime createdAt; // MappingException: requires exactly one column
// after — single column
@CurrentTimestamp(event = EventType.INSERT)
@Column(name = "created_at", nullable = false)
LocalDateTime createdAt; Defensive patterns
Strategy: validation
Validate before calling
// Fail fast on @CurrentTimestamp members mapped to multiple columns, before booting
static void checkCurrentTimestampMappings(Class<?>... entities) {
for (Class<?> entity : entities) {
for (Field f : entity.getDeclaredFields()) {
if (f.isAnnotationPresent(CurrentTimestamp.class)) {
Columns cols = f.getAnnotation(Columns.class);
if (cols != null && cols.columns().length != 1) {
throw new IllegalStateException(entity.getSimpleName() + "." + f.getName()
+ ": @CurrentTimestamp requires a single-column mapping");
}
}
}
}
} Prevention
- Keep @CurrentTimestamp on single-column java.time fields
- Prefer built-in java.time mappings over multi-column UserTypes for timestamps
- Run a SessionFactory bootstrap test per persistence unit in CI
When it happens
Trigger: Annotating a property with @CurrentTimestamp whose mapping occupies more or less than one column: a property with @Columns (multiple @Column entries), a CompositeUserType spanning several columns (e.g. an offset-time or range split across columns), or an embeddable-level timestamp mapped to several columns.
Common situations: java.time or vendor types (TIMESTAMP WITH TIME ZONE split into two columns, TSRANGE) mapped via composite user types; migrating a field from a single-column mapping to a multi-column type while keeping @CurrentTimestamp; imported mappings that combine generated timestamps with @Columns.
Related errors
- Attribute was not a Map : ${collectionMemberType}
- Unable to create AttributeConverter instance
- Property '${path}' specifies ${columnCount} '@AttributeOverr
- '@ColumnDefault' may only be applied to single-column mappin
- '@GeneratedColumn' may only be applied to single-column mapp
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/bd1f2714b7b1e7ac.
Report an issue: GitHub.