hibernate/hibernate-orm · error · MappingException
Multiple check constraints not supported for aggregate colum
Error message
Multiple check constraints not supported for aggregate columns
What it means
When a table column is an aggregate (embeddable/component) rendered inline, Hibernate can attach at most one check constraint to the sub-column. If the mapped sub-column accumulates more than one check definition, this MappingException aborts CREATE TABLE string building. It flags an over-constrained embedded mapping, not a database runtime error.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java:399
);
if ( subColumn.isNullable() ) {
buf.append( ')' );
}
separator = " and ";
}
}
}
}
return separator;
}
private static String getCheckConstraint(Column subColumn) {
final var checkConstraints = subColumn.getCheckConstraints();
if ( checkConstraints.isEmpty() ) {
return null;
}
else if ( checkConstraints.size() > 1 ) {
throw new MappingException( "Multiple check constraints not supported for aggregate columns" );
}
else {
return checkConstraints.get(0).getConstraint();
}
}
private String tableCreateString(Table table) {
final String createTableString =
table.hasPrimaryKey()
? dialect.getCreateTableString()
: dialect.getCreateMultisetTableString();
final String type = table.getType();
return isBlank( type )
? createTableString
: createTableString.replaceFirst( " (?i:table)",
' ' + type + " table" );
}
View on GitHub (pinned to fad1729dce)
Solutions
- Find the embeddable sub-column named by the failing mapping and keep a single check constraint on it, merging conditions with AND if both must hold.
- Move additional constraints out of the aggregate: declare them as table-level @Check on the owning entity or handle them in migration scripts.
- De-duplicate the mapping layers (remove the XML check or the annotation check) so only one definition reaches the sub-column.
Example fix
<!-- before: same component column carries two checks -->
<component name="address" class="Address">
<property name="zip">
<column name="zip" check="length(zip) > 0"/>
<column name="zip" check="zip ~ '^[0-9]+$'"/>
</property>
</component>
<!-- after: one merged check -->
<component name="address" class="Address">
<property name="zip">
<column name="zip" check="length(zip) > 0 AND zip ~ '^[0-9]+$'"/>
</property>
</component> Defensive patterns
Strategy: validation
Validate before calling
// after building Metadata, assert no aggregate sub-column carries more than one check
metadata.getDatabase().getNamespaces().stream()
.flatMap(ns -> ns.getTables().stream())
.flatMap(t -> Stream.concat(t.getColumns().stream(),
t.getColumnIterator /* embeddable sub-columns */))
.forEach(c -> { if (c.getCheckConstraints().size() > 1
&& cisAggregateSubColumn(c)) { throw new IllegalStateException("Multiple checks on " + c); } }); Try / catch
try {
new SchemaExport(metadata).createOnly();
} catch (MappingException e) {
if (e.getMessage() != null && e.getMessage().equals("Multiple check constraints not supported for aggregate columns")) {
// reduce the embeddable sub-column to one merged check (AND) and retry
} else { throw e; }
} Prevention
- Declare at most one check per embeddable sub-column; merge conditions with AND.
- Prefer table-level @Check on the owning entity over per-subcolumn checks inside aggregates.
- When migrating XML to annotations, remove the old check attributes instead of layering them.
When it happens
Trigger: An @Embeddable (or hbm.xml component) used via @Embedded/@EmbeddedId where one of its columns ends up with multiple check constraints: checks declared at more than one mapping layer for the same sub-column, duplicated column definitions inside the component, or programmatic metadata adding several checks to one component column. Thrown from getCheckConstraint while StandardTableExporter renders the aggregate column.
Common situations: Embeddables shared across entities where both the embeddable and each owner add checks; XML mappings migrated to annotations leaving the old check attribute active; duplicated <column check=...> entries in component property mappings.
Related errors
- '@Check' may only be applied to single-column mappings but '
- '@GeneratedColumn' may only be applied to single-column mapp
- Property '${path}' specifies ${columnCount} '@AttributeOverr
- '@ColumnDefault' may only be applied to single-column mappin
- unknown type: {sqlTypeCode}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/add36224d10b02e5.
Report an issue: GitHub.