hibernate/hibernate-orm · error · MappingException

Unable to determine foreign key target Type for many-to-one

Error message

Unable to determine foreign key target Type for many-to-one or one-to-one mapping: referenced-entity-name=[${associatedEntityName}], referenced-entity-attribute-name=[${lhsPropertyName}]

What it means

EntityType.requireIdentifierOrUniqueKeyType (EntityType.java:734-744) resolves the type of the foreign key target for a many-to-one/one-to-one: the referenced entity's identifier, or the property referenced by property-ref/referencedPropertyName. When getIdentifierOrUniqueKeyType returns null - the referenced entity or referenced property could not be resolved from the mapping metadata - it throws MappingException naming the referenced entity and the referenced attribute, so you can trace exactly which association is broken.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/EntityType.java:742

			result = factory.getMappingMetamodel().getEntityDescriptor( entityName )
					.loadByUniqueKey( uniqueKeyPropertyName, key, session );
			if ( result != null ) {
				// If the entity was not in the persistence context,
				// but was found now, add it to the persistence context
				persistenceContext.addEntity( entityUniqueKey, result );
			}
		}
		else {
			result = entity;
		}

		return result == null ? null : persistenceContext.proxyFor( result );
	}

	protected Type requireIdentifierOrUniqueKeyType(MappingContext mapping) {
		final Type targetType = getIdentifierOrUniqueKeyType( mapping );
		if ( targetType == null ) {
			throw new MappingException(
					"Unable to determine foreign key target Type for many-to-one or one-to-one mapping: " +
							"referenced-entity-name=[" + getAssociatedEntityName() +
							"], referenced-entity-attribute-name=[" + getLHSPropertyName() + "]"
			);
		}
		return targetType;
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Verify the referenced entity is mapped: annotated @Entity and included in the persistence unit / scanned package.
  2. Fix the target name spelled in the message: correct targetEntity/class FQN or entityName; remove stale property-ref/referencedPropertyName values.
  3. Ensure the referenced property on the target exists and is the identifier or a unique column, and that the target's own @Id/@EmbeddedId/@IdClass mapping resolves cleanly.
  4. Enable startup logging for mapping metadata to see the preceding warnings about unresolvable classes/properties.

Example fix

// before
@Entity public class Order {
    @ManyToOne(targetEntity = Custmr.class) // wrong/unknown target
    private Custmr customer;
}

// after
@Entity public class Order {
    @ManyToOne(fetch = FetchType.LAZY)
    private Customer customer; // Customer is @Entity and in the persistence unit
}
Defensive patterns

Strategy: validation

Validate before calling

// Startup smoke test: every association must resolve its target in this persistence unit
for (EntityType<?> et : emf.getMetamodel().getEntities()) {
    for (SingularAttribute<?, ?> a : et.getSingularAttributes()) {
        if (a.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE
                || a.getPersistentAttributeType() == PersistentAttributeType.ONE_TO_ONE) {
            Type<?> target = ((SingularAttribute<?, ?>) a).getType();
            if (target.getPersistenceType() != Type.PersistenceType.ENTITY) {
                throw new IllegalStateException(
                    et.getName() + "." + a.getName() + " references unresolvable target");
            }
        }
    }
}

Type guard

static boolean isMappedEntity(Metamodel mm, Class<?> target) {
    try { mm.entity(target); return true; }
    catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
    return em.createEntityManager(...); // first use / bootstrap
} catch (PersistenceException e) {
    if (e.getCause() instanceof MappingException me
            && me.getMessage().contains("Unable to determine foreign key target Type")) {
        throw new ConfigurationException(
            "Broken @ManyToOne/@OneToOne referenced in: " + me.getMessage(), me);
    }
    throw e;
}

Prevention

When it happens

Trigger: @ManyToOne/@OneToOne pointing at a class that is not a registered entity (missing @Entity, not in the persistence unit / not scanned); a wrong entityName in @ManyToOne(targetEntity=...) or <many-to-one class=...>; @OneToOne(mappedBy/referencedPropertyName) naming a property that does not exist on the target; hbm.xml <many-to-one> with a property-ref to a non-unique or missing property; circular mappings where the target's id type is itself unresolved.

Common situations: Entities excluded by explicit class lists in persistence.xml; annotation scanning gaps after moving classes between modules; refactoring property names referenced by mappedBy/property-ref; copy-pasted mappings referencing old class names; @IdClass/@EmbeddedId on the target that fails to resolve earlier.

Related errors


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