{"record":{"id":"bd1f2714b7b1e7ac","repo":"hibernate/hibernate-orm","slug":"currenttimestampgeneration-requires-exactly-one-co","errorCode":null,"errorMessage":"CurrentTimestampGeneration requires exactly one column","messagePattern":"CurrentTimestampGeneration requires exactly one column","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/generator/internal/CurrentTimestampGeneration.java","lineNumber":131,"sourceCode":"\t\tdelegate = getGeneratorDelegate( annotation.source(), context.getType(), context );\n\t\teventTypes = INSERT_AND_UPDATE;\n\t\tpropertyType = getPropertyType( context );\n\t\tversion = isVersion( context );\n\t\tnotNull( context );\n\t}\n\n\tprivate static boolean isVersion(GeneratorCreationContext context) {\n\t\tfinal var persistentClass = context.getPersistentClass();\n\t\treturn persistentClass != null\n\t\t\t&& context.getProperty() == persistentClass.getVersion();\n\t}\n\n\tprivate static void notNull(GeneratorCreationContext context) {\n\t\tfinal var property = context.getProperty();\n\t\tproperty.setOptional( false );\n\t\tfinal var columns = property.getColumns();\n\t\tif ( columns.size() != 1 ) {\n\t\t\tthrow new MappingException( \"CurrentTimestampGeneration requires exactly one column\" );\n\t\t}\n\t\tcolumns.get( 0 ).setNullable( false );\n\t}\n\n\tprivate static GeneratorDelegate getGeneratorDelegate(\n\t\t\tSourceType source,\n\t\t\tType type,\n\t\t\tGeneratorCreationContext context) {\n\t\treturn getGeneratorDelegate( source, type.getReturnedClass(), context );\n\t}\n\n\tstatic GeneratorDelegate getGeneratorDelegate(\n\t\t\tSourceType source,\n\t\t\tClass<?> propertyType,\n\t\t\tGeneratorCreationContext context) {\n\t\treturn switch (source) {\n\t\t\tcase DB -> null;\n\t\t\tcase VM -> getGeneratorDelegate( propertyType, getBaseClock( context ), getPrecision( context ) );","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/generator/internal/CurrentTimestampGeneration.java#L113-L149","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before — @CurrentTimestamp on a 2-column mapping\n@CurrentTimestamp(event = EventType.INSERT)\n@Columns({@Column(name = \"created_date\"), @Column(name = \"created_time\")})\nLocalDateTime createdAt;   // MappingException: requires exactly one column\n\n// after — single column\n@CurrentTimestamp(event = EventType.INSERT)\n@Column(name = \"created_at\", nullable = false)\nLocalDateTime createdAt;","handlingStrategy":"validation","validationCode":"// Fail fast on @CurrentTimestamp members mapped to multiple columns, before booting\nstatic void checkCurrentTimestampMappings(Class<?>... entities) {\n    for (Class<?> entity : entities) {\n        for (Field f : entity.getDeclaredFields()) {\n            if (f.isAnnotationPresent(CurrentTimestamp.class)) {\n                Columns cols = f.getAnnotation(Columns.class);\n                if (cols != null && cols.columns().length != 1) {\n                    throw new IllegalStateException(entity.getSimpleName() + \".\" + f.getName()\n                            + \": @CurrentTimestamp requires a single-column mapping\");\n                }\n            }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["hibernate","current-timestamp","value-generation","multi-column","mapping","bootstrap"],"backgroundTag":"annotation-mapping-violation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}