hibernate/hibernate-orm · error · AnnotationException
Column mappings for property '${propertyName}' mix insertabl
Error message
Column mappings for property '${propertyName}' mix insertable with 'insertable=false' What it means
The insertability leg of AnnotatedColumns.checkPropertyConsistency: consecutive non-formula columns of one property must agree on insertable. If one column writes on insert and a sibling of the same property has insertable = false, the mapping is contradictory and Hibernate throws this AnnotationException while binding the property.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumns.java:169
}
public void addColumn(AnnotatedColumn child) {
columns.add( child );
}
public void checkPropertyConsistency() {
if ( columns.size() > 1 ) {
for ( int currentIndex = 1; currentIndex < columns.size(); currentIndex++ ) {
final AnnotatedColumn current = columns.get( currentIndex );
final AnnotatedColumn previous = columns.get( currentIndex - 1 );
if ( !current.isFormula() && !previous.isFormula() ) {
if ( current.isNullable() != previous.isNullable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix nullable with 'not null'"
);
}
if ( current.isInsertable() != previous.isInsertable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix insertable with 'insertable=false'"
);
}
if ( current.isUpdatable() != previous.isUpdatable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix updatable with 'updatable=false'"
);
}
if ( !current.getExplicitTableName().equals( previous.getExplicitTableName() ) ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix distinct secondary tables"
);
}
}
}
}
}
}View on GitHub (pinned to fad1729dce)
Solutions
- Set the same insertable value on every column of the property
- If one part must stay read-only, map it as its own property (e.g. a separate read-only field) rather than mixing flags inside one mapping
- After fixing, verify updatable flags and table names too - the same consistency check validates them next
Example fix
// before: mixed insertable within one property
@Type(MoneyType.class)
@Columns({
@Column(name = "amount"), // insertable = true
@Column(name = "currency", insertable = false) // mixes -> error
})
private Money price;
// after: consistent flags (or split into separate properties)
@Type(MoneyType.class)
@Columns({
@Column(name = "amount"),
@Column(name = "currency")
})
private Money price; Defensive patterns
Strategy: validation
Validate before calling
// Before boot: all columns of one multi-column property must agree on insertable
static boolean insertableFlagsConsistent(Class<?> entity) {
for (Field f : entity.getDeclaredFields()) {
Columns cols = f.getAnnotation(Columns.class);
if (cols == null || cols.value().length < 2) continue;
boolean first = cols.value()[0].insertable();
for (Column c : cols.value()) {
if (c.insertable() != first) 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
- Never mix writable and read-only columns inside one property mapping
- Model read-only companions as separate properties
- When changing one column's flags, sweep the whole @Columns/@AttributeOverrides block
When it happens
Trigger: A multi-column property where @Column/@AttributeOverride entries mix insertable = true (default) and insertable = false - commonly the read-only half of a composite mapping left non-insertable while the other half stays writable.
Common situations: Making one column of a composite read-only for trigger/generated-value reasons while forgetting the sibling columns; copy-pasted override blocks with stale insertable flags; splitting a property's columns across insert/update strategies.
Related errors
- Column mappings for property '${propertyName}' mix nullable
- Property '${path}' specifies ${columnCount} '@AttributeOverr
- Attribute was not a Map : ${collectionMemberType}
- Unable to create AttributeConverter instance
- '@ColumnDefault' may only be applied to single-column mappin
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/1f72d1543a606fc0.
Report an issue: GitHub.