hibernate/hibernate-orm · error · AnnotationException

Column mappings for property '${propertyName}' mix distinct

Error message

Column mappings for property '${propertyName}' mix distinct secondary tables

What it means

While binding a property that maps several columns, Hibernate found that those columns declare different 'table' attributes, i.e. they would live in distinct secondary tables (@Table/@SecondaryTable joined to the primary). A property's columns must all live in one table, so Hibernate refuses the mapping. Checked in the same consistency pass as nullable/insertable/updatable.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumns.java:179

				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

  1. Pick ONE table for the property and set the same 'table' attribute on every @Column of that property (or remove the attribute entirely to use the primary table).
  2. Verify the secondary table names match exactly (case-sensitivity under the quoting/naming strategy) with the @SecondaryTable declarations on the entity.
  3. If the columns genuinely must live in different tables, map them as separate properties, each consistent.

Example fix

// before
@Entity
@SecondaryTable(name = "addr")
class Customer {
    @Columns({
        @Column(name = "street", table = "addr"),
        @Column(name = "zip", table = "customer") // distinct tables -> error
    })
    private Address address;
}

// after
@Entity
@SecondaryTable(name = "addr")
class Customer {
    @Columns({
        @Column(name = "street", table = "addr"),
        @Column(name = "zip", table = "addr") // same secondary table
    })
    private Address address;
}
Defensive patterns

Strategy: validation

Validate before calling

// Before bootstrap: assert one table per property across its columns
for (Field f : cls.getDeclaredFields()) {
    Column[] cols = f.getAnnotationsByType(Column.class);
    Set<String> tables = Arrays.stream(cols).map(Column::table).collect(toSet());
    if (tables.size() > 1) {
        throw new IllegalStateException(cls.getName() + "." + f.getName()
            + " spans multiple tables: " + tables);
    }
}

Try / catch

try {
    SessionFactory sf = cfg.buildSessionFactory();
} catch (AnnotationException e) {
    // 'mix distinct secondary tables' -> check table= attributes on @Column
    log.error("Column/table inconsistency in mapping: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: One @Column of the property specifies 'table = "secondary_a"' while another specifies 'table = "secondary_b"' or no table (primary table); an override changes only one column's table; the property mixes a primary-table column with a secondary-table column.

Common situations: Splitting a multi-column type or embeddable across two secondary tables; copy-pasting an @Column from another entity whose class used a different @SecondaryTable name; overriding an embedded mapping in a subclass that defines different secondary tables than the original.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/4b4722efa0fe10ac. Report an issue: GitHub.