hibernate/hibernate-orm · error · MappingException

A '@JoinColumn' references a column named '{}' but the targe

Error message

A '@JoinColumn' references a column named '{}' but the target entity '{}' has no property which maps to this column

What it means

A '@JoinColumn(referencedColumnName=...)' names a column on the target entity, but no property of that entity maps the column, so Hibernate cannot resolve the reference. The code deliberately rethrows it as FailedSecondPassException so the metadata collector can retry later passes in case the binding is merely out of order; if the error survives to the end of bootstrap, the reference itself is wrong.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedJoinColumns.java:342

	 * Determine if the given {@link AnnotatedJoinColumns} represent a reference to
	 * the primary key of the given {@link PersistentClass}, or whether they reference
	 * some other combination of mapped columns.
	 */
	public ForeignKeyType getReferencedColumnsType(PersistentClass referencedEntity) {
		if ( referencedProperty != null ) {
			return NON_PRIMARY_KEY_REFERENCE;
		}

		if ( columns.isEmpty() ) {
			return ForeignKeyType.IMPLICIT_PRIMARY_KEY_REFERENCE; //shortcut
		}

		final var firstColumn = columns.get( 0 );
		final var context = getBuildingContext();
		final Object columnOwner = findReferencedColumnOwner( referencedEntity, firstColumn, context );
		if ( columnOwner == null ) {
			try {
				throw new MappingException( "A '@JoinColumn' references a column named '"
						+ firstColumn.getReferencedColumn() + "' but the target entity '"
						+ referencedEntity.getEntityName() + "' has no property which maps to this column" );
			}
			catch ( MappingException me ) {
				// we throw a recoverable exception here in case this
				// is merely an ordering issue, so that the SecondPass
				// will get reprocessed later
				throw new FailedSecondPassException( me.getMessage(), me );
			}
		}
		final var table = table( columnOwner );
//		final List<Selectable> keyColumns = referencedEntity.getKey().getSelectables();
		final var keyColumns =
				table.getPrimaryKey() == null
						? referencedEntity.getKey().getSelectables()
						: table.getPrimaryKey().getColumns();
		boolean explicitColumnReference = false;
		for ( var column : columns ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Correct referencedColumnName to exactly match the mapped column of a real property on the target entity.
  2. Add or restore the target property that maps the referenced column (e.g. a @Column(name="...") field or unique @ManyToOne).
  3. If you do not need a non-PK reference, remove referencedColumnName so the join defaults to the target's primary key.

Example fix

// before
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_email", referencedColumnName = "email_address") // target maps 'email', not 'email_address'
private User user;

// after
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_email", referencedColumnName = "email")
private User user;
Defensive patterns

Strategy: validation

Validate before calling

// Guard: referencedColumnName must match a mapped column on the target entity
Class<?> target = User.class;
Set<String> mapped = new HashSet<>();
for (Field f : target.getDeclaredFields()) {
    Column c = f.getAnnotation(Column.class);
    if (c != null) mapped.add(c.name().isEmpty() ? f.getName() : c.name());
}
JoinColumn jc = orderField.getAnnotation(JoinColumn.class);
if (jc != null && !jc.referencedColumnName().isEmpty()
        && !mapped.contains(jc.referencedColumnName())) {
    throw new IllegalStateException("referencedColumnName '" + jc.referencedColumnName()
        + "' is not mapped by " + target.getSimpleName());
}

Try / catch

try {
    factory = cfg.buildSessionFactory();
} catch (FailedSecondPassException | AnnotationException e) {
    // Hibernate retries ordering internally; if it still fails, the reference is wrong.
    // 'has no property which maps to this column' -> fix referencedColumnName
    throw newConfigurationException("Unresolvable join column reference", e);
}

Prevention

When it happens

Trigger: referencedColumnName has a typo or wrong case; the referenced column exists in the database but the target entity has no mapped property for it (no field maps that column); the target attribute is mapped by a @Formula rather than a real column; the FK targets a natural key property that was never mapped.

Common situations: Hand-typed referencedColumnName strings drifted from the schema; joining to a unique business column (SSN, email) that the target entity does not map as a field; databases with case-sensitive identifiers; mappings that worked when the column was the PK but broke after switching to a natural-key reference.

Related errors


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