hibernate/hibernate-orm · error · AnnotationException

Identifier field '{}' named in '@MapsId' does not exist in e

Error message

Identifier field '{}' named in '@MapsId' does not exist in entity '{}'

What it means

'@MapsId("fieldName")' names an attribute that must be part of the entity's identifier — a field of an @EmbeddedId class or the simple/@IdClass id property. resolveMapsId() looked it up via persistentClass.getIdentifier()/getProperty(mapsId) and caught a MappingException because no such identifier attribute exists, so the derived-id mapping cannot be wired.

Source

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

		else {
			for ( var joinColumn : joinColumns ) {
				buildExplicitJoinTableJoinColumn( parent, propertyHolder, inferredData, joinColumn );
			}
		}
		handlePropertyRef( inferredData.getAttributeMember(), parent );
		return parent;
	}

	Property resolveMapsId() {
		final var persistentClass = getPropertyHolder().getPersistentClass();
		final var identifier = persistentClass.getIdentifier();
		try {
			return identifier instanceof Component embeddedIdType
					? embeddedIdType.getProperty( mapsId )   // an @EmbeddedId
					: persistentClass.getProperty( mapsId );  // a simple id or an @IdClass
		}
		catch (MappingException me) {
			throw new AnnotationException( "Identifier field '" + mapsId
					+ "' named in '@MapsId' does not exist in entity '" + persistentClass.getEntityName() + "'",
					me );
		}
	}

	public List<AnnotatedJoinColumn> getJoinColumns() {
		return columns;
	}

	@Override
	public void addColumn(AnnotatedColumn child) {
		if ( !( child instanceof AnnotatedJoinColumn joinColumn ) ) {
			throw new AssertionFailure( "wrong sort of column" );
		}
		addColumn( joinColumn );
	}

	public void addColumn(AnnotatedJoinColumn child) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Match the @MapsId value EXACTLY (case-sensitive) to an attribute of the @EmbeddedId embeddable, or to the simple id property name.
  2. If the id is a simple @Id field, either omit the value ('@MapsId' with no argument) or use the id field's name.
  3. Re-run the bootstrap (test that builds a SessionFactory) after every rename of identifier fields.

Example fix

// before
@Embeddable
class OrderId implements Serializable {
    Long number; // no 'id' field
}

@Entity
class Shipment {
    @EmbeddedId OrderId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("id") // does not exist in OrderId
    Order order;
}

// after
@Entity
class Shipment {
    @EmbeddedId OrderId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("number")
    Order order;
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard: @MapsId value must be a field of the embedded id (or the simple id)
for (Field f : cls.getDeclaredFields()) {
    MapsId mapsId = f.getAnnotation(MapsId.class);
    if (mapsId != null && !mapsId.value().isEmpty()) {
        Field idField = cls.getDeclaredField("id");
        Class<?> idType = idField.getType();
        if (idType.isAnnotationPresent(Embeddable.class)
                && Arrays.stream(idType.getDeclaredFields())
                         .noneMatch(x -> x.getName().equals(mapsId.value()))) {
            throw new IllegalStateException("@MapsId(" + mapsId.value()
                + ") is not an attribute of " + idType.getSimpleName());
        }
    }
}

Try / catch

try {
    Metadata md = sources.buildMetadata();
} catch (AnnotationException e) {
    // 'Identifier field ... does not exist' -> fix the mapsId string to match the id attribute
    throw newConfigurationException("Bad @MapsId target", e);
}

Prevention

When it happens

Trigger: '@MapsId("userId")' on an association when the entity's @EmbeddedId class has no 'userId' field; a typo or case mismatch in the mapsId value; using the Java field name of the association itself instead of the id attribute; @MapsId on an entity whose id is @GeneratedValue with a different property name.

Common situations: Renames during refactoring that change the embeddable's field but not the @MapsId string; switching between @IdClass and @EmbeddedId without updating mapsId values; following derived-id examples and mistaking the FK property for the id property.

Related errors


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