hibernate/hibernate-orm · error · PropertyNotFoundException
Could not resolve attribute '${name}' of any mapping (must b
Error message
Could not resolve attribute '${name}' of any mapping (must be one of 'class', 'id') What it means
AnyType.getPropertyIndex (AnyType.java:394) only knows the two synthetic sub-attributes of an @Any mapping: 'class' (the discriminator) and 'id' (the foreign key). Any other attribute name asked for on an any-typed path throws PropertyNotFoundException with this message, listing the two legal names.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/AnyType.java:402
}
private static final String[] PROPERTY_NAMES = new String[] { "class", "id" };
@Override
public String[] getPropertyNames() {
return PROPERTY_NAMES;
}
@Override
public int getPropertyIndex(String name) {
if ( PROPERTY_NAMES[0].equals( name ) ) {
return 0;
}
else if ( PROPERTY_NAMES[1].equals( name ) ) {
return 1;
}
throw new PropertyNotFoundException( "Could not resolve attribute '" + name
+ "' of any mapping (must be one of 'class', 'id')" );
}
@Override
public Object getPropertyValue(Object component, int i, SharedSessionContractImplementor session) throws HibernateException {
return i==0
? session.bestGuessEntityName( component )
: getIdentifier( component, session );
}
@Override
public Object[] getPropertyValues(Object component, SharedSessionContractImplementor session) throws HibernateException {
return new Object[] {
session.bestGuessEntityName( component ),
getIdentifier( component, session )
};
}
View on GitHub (pinned to fad1729dce)
Solutions
- Query only the two valid sub-attributes: compare the discriminator ('class') and the id, e.g. 'where d.owner.class = User and d.owner.id = :id' (or type(...) checks per HQL dialect support).
- If you need to filter by fields of the target entity, load the target by the stored (class, id) pair in a second query or restructure to @ManyToOne so real joins are possible.
- Regenerate derived queries after changing an association from @ManyToOne to @Any.
Example fix
// before (owner is @Any)
List<Doc> docs = session.createQuery(
"from Doc d where d.owner.name = :n", Doc.class)
.setParameter("n", "alice")
.getResultList();
// after: constrain via discriminator + id, then load targets
List<Doc> docs = session.createQuery(
"from Doc d where d.owner.class = User and d.owner.id = :uid", Doc.class)
.setParameter("uid", aliceId)
.getResultList(); Defensive patterns
Strategy: validation
Validate before calling
// Validate an attribute path against the metamodel before running HQL
static void checkPath(Metamodel mm, Class<?> root, String... path) {
Bindable<?> b = mm.entity(root);
for (String name : path) {
Attribute<?, ?> a = ((ManagedType<?>) b).getAttribute(name); // throws IllegalArgumentException early
b = (a instanceof SingularAttribute<?, ?> sa) ? sa.getType() : null;
}
}
checkPath(mm, Doc.class, "owner", "id"); // ok for @Any; "name" would fail with a clear message Type guard
static boolean isAnyMapped(Attribute<?, ?> attr) {
return attr.getJavaMember() instanceof Field f
&& (f.isAnnotationPresent(Any.class) || f.isAnnotationPresent(ManyToAny.class));
} Try / catch
try {
return session.createQuery(jpql, Doc.class).getResultList();
} catch (IllegalArgumentException e) {
if (e.getCause() instanceof PropertyNotFoundException pnfe
&& pnfe.getMessage().contains("of any mapping")) {
throw new QueryValidationException(
"Only 'class' and 'id' are queryable on an @Any attribute: " + jpql, e);
}
throw e;
} Prevention
- Treat @Any attributes as (class, id) pairs in every query; never navigate into target fields.
- When converting @ManyToOne to @Any, grep queries for paths through the renamed attribute.
When it happens
Trigger: HQL/JPQL or Criteria that navigates into an @Any/@ManyToAny property with an attribute other than class or id, e.g. 'from Doc d where d.owner.name = :n' where owner is @Any; also programmatic calls to AnyType.getPropertyIndex(name), e.g. via property resolution APIs or reflection-based mapping validation.
Common situations: Developers treating @Any like a real entity association in queries; query generators that walk metamodel attributes uniformly and emit nested paths over any-typed members; refactoring a @ManyToOne to @Any and leaving old JPQL path expressions in place.
Related errors
- Incorrect query result type: query produces '%s' but type '%
- Entity discriminator cannot be de-referenced
- Expecting a SELECT Query [%s], but found %s
- any types do not have a unique referenced persister
- Could not resolve attribute '${name}' of '${returnedClassNam
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/1783da3ccb4480c1.
Report an issue: GitHub.