hibernate/hibernate-orm · error · IllegalArgumentException
Unable to locate IdClass attributes [{}]
Error message
Unable to locate IdClass attributes [{}] What it means
The entity is annotated with @IdClass (hasIdClass() is true), but visiting its attributes collected zero members into nonAggregatedIdAttributes — Hibernate cannot find the id attributes that the @IdClass promises. This signals broken mapping metadata: the id-class fields and the entity's @Id fields do not line up, or attributes were never registered.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java:232
visitIdClassAttributes( attributes::add );
return attributes.isEmpty() ? null : attributes;
}
else {
return null;
}
}
@Override
@Nonnull
public Set<SingularAttribute<? super J, ?>> getIdClassAttributes() {
if ( !hasIdClass() ) {
throw new IllegalArgumentException( "This class [" + getJavaType() + "] does not define an IdClass" );
}
final Set<SingularAttribute<? super J, ?>> attributes = new HashSet<>();
visitIdClassAttributes( attributes::add );
if ( attributes.isEmpty() ) {
throw new IllegalArgumentException( "Unable to locate IdClass attributes [" + getJavaType() + "]" );
}
return attributes;
}
@Override
public void visitIdClassAttributes(@Nonnull Consumer<SingularPersistentAttribute<? super J, ?>> attributeConsumer) {
if ( nonAggregatedIdAttributes != null ) {
nonAggregatedIdAttributes.forEach( attributeConsumer );
}
else {
final var superType = getSuperType();
if ( superType != null ) {
//noinspection rawtypes, unchecked
superType.visitIdClassAttributes( (Consumer) attributeConsumer );
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Make every field of the @IdClass a public @Id field on the entity with the same name and type
- Give the @IdClass a no-arg constructor and correct equals/hashCode (spec requirement) and re-verify startup validation
- Prefer @EmbeddedId — same composite semantics, fewer matching rules, and getId()/getIdType() then work
Example fix
// before
class OrderId implements Serializable { Long customerNbr; Date orderDay; } // names differ
@Entity @IdClass(OrderId.class)
class Order { @Id Long customerNumber; @Id Date orderDate; } // -> empty id-class attributes
// after
class OrderId implements Serializable { Long customerNumber; Date orderDate; } // match names+types Defensive patterns
Strategy: validation
Validate before calling
// At startup, verify @IdClass fields match @Id fields on the entity
Class<?> idClass = /* from @IdClass */;
for (Field f : idClass.getDeclaredFields()) {
Field entityField = entityClass.getDeclaredField(f.getName()); // NoSuchElementException = mismatch
if (!entityField.isAnnotationPresent(Id.class)) throw new IllegalStateException("not @Id: " + f.getName());
if (!f.getType().equals(entityField.getType())) throw new IllegalStateException("type mismatch: " + f.getName());
} Try / catch
try {
return type.getIdClassAttributes();
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Unable to locate IdClass attributes")) {
// mapping defect: @IdClass fields do not line up with entity @Id fields
throw new IllegalStateException("Broken @IdClass mapping on " + type.getTypeName(), e);
}
throw e;
} Prevention
- Keep @IdClass field names and types byte-identical to the entity's @Id fields
- Give id classes a no-arg constructor and implement equals/hashCode
- Consider @EmbeddedId to avoid the matching rules entirely
- Add a startup unit test per composite-key entity that calls getIdClassAttributes()
When it happens
Trigger: An @IdClass entity where the id-class field names/types do not match the entity's @Id fields; programmatic/generateable mappings that declare an id class without marking the corresponding attributes as ids; bootstrap ordering issues during metamodel construction.
Common situations: Typos between @IdClass field names and entity @Id fields; changing field names in the id class only; using lombok/bytecode enhancement that renames or hides fields; Hibernate version upgrades changing id-class discovery rules.
Related errors
- Could not resolve attribute '{}' of '{}'
- Illegal call to IdentifiableType#getId for class [{}] define
- This class [{}] does not define an IdClass
- Property '" + getPath( propertyHolder, inferredData ) + "' b
- Non-aggregate composite paths cannot be TREAT-ed
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/36132c1b858278c9.
Report an issue: GitHub.