hibernate/hibernate-orm · error · IllegalArgumentException
No singular attribute named '{}' and of type '{}' in type '{
Error message
No singular attribute named '{}' and of type '{}' in type '{}' What it means
getDeclaredSingularAttribute(name, Class) failed because either no singular attribute with that name exists on the type, or one exists but its Java type does not match the requested Class (hasMatchingReturnType). The message includes the requested type only when non-null, so 'of type null' means the lookup by name itself failed.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java:332
@Override
@Nullable
public SqmSingularPersistentAttribute<J, ?> findDeclaredSingularAttribute(@Nonnull String name) {
return declaredSingularAttributes.get( name );
}
@Override
@Nonnull
public <Y> SingularPersistentAttribute<J, Y> getDeclaredSingularAttribute(@Nonnull String name, @Nonnull Class<Y> javaType) {
return checkTypeForSingleAttribute( findDeclaredSingularAttribute( name ), name, javaType );
}
private <K,Y> SqmSingularPersistentAttribute<K,Y> checkTypeForSingleAttribute(
SqmSingularPersistentAttribute<K,?> attribute,
String name,
Class<Y> javaType) {
if ( attribute == null || !hasMatchingReturnType( attribute, javaType ) ) {
throw new IllegalArgumentException(
"No singular attribute named '" + name
+ ( javaType != null ? "' and of type '" + javaType.getName() : "" )
+ "' in type '" + hibernateTypeName + "'"
);
}
else {
@SuppressWarnings("unchecked")
final SqmSingularPersistentAttribute<K, Y> narrowed =
(SqmSingularPersistentAttribute<K, Y>) attribute;
return narrowed;
}
}
private <T, Y> boolean hasMatchingReturnType(SingularAttribute<T, ?> attribute, Class<Y> javaType) {
return javaType == null
|| attribute.getJavaType().equals( javaType )
|| isPrimitiveVariant( attribute, javaType );
}View on GitHub (pinned to fad1729dce)
Solutions
- Verify the attribute exists and its exact Java type: findDeclaredSingularAttribute(name) then inspect getJavaType()
- Use the untyped overload or CollectionAttribute APIs for plural attributes
- Use getId-style matching with the actual type from attribute.getJavaType() rather than a hard-coded class
Example fix
// before
var a = productType.getDeclaredSingularAttribute("tags", String.class); // tags is a Set -> throws
// after
var a = productType.getDeclaredPluralAttribute... // if plural
// or for singular: type matches attribute.getJavaType() Defensive patterns
Strategy: validation
Validate before calling
// Look up untyped first, then verify the Java type
var attr = managedType.getDeclaredSingularAttribute(name); // untyped, null-safe? throws if missing
// safer:
for (Attribute<?,?> a : managedType.getAttributes()) {
if (a.getName().equals(name) && a instanceof SingularAttribute<?,?> sa
&& expected.isAssignableFrom(sa.getJavaType())) { /* safe to use */ }
} Type guard
static boolean isSingularOf(ManagedType<?> type, String name, Class<?> expected) {
for (Attribute<?,?> a : type.getAttributes()) {
if (a.getName().equals(name)
&& a instanceof SingularAttribute<?,?> sa
&& expected.isAssignableFrom(sa.getAttributeJavaType())) return true;
}
return false;
} Try / catch
try {
return type.getDeclaredSingularAttribute(name, cls);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("No singular attribute named")) {
// name wrong, or type mismatch, or attribute is plural
throw new NoSuchFieldException(name + " on " + type.getTypeName());
}
throw e;
} Prevention
- Inspect the real Java type via findDeclaredSingularAttribute(name) before the typed call
- Keep typed metamodel calls in one layer so type refactors surface immediately
- Remember plural attributes fail the singular lookup — choose the right API
When it happens
Trigger: Calling getDeclaredSingularAttribute("name", Integer.class) when 'name' is a String or is a plural/collection attribute; requesting an inherited attribute through the declared variant; misspelled name.
Common situations: Refactoring an attribute's type (e.g. Integer -> Long) while callers still request the old wrapper. Attempting to read a List/Set/Map attribute through the singular API. Base-class attributes with the declared variant.
Related errors
- Attribute [%s#%s : %s] not castable to requested type [%s]
- Unable to locate %s with the given name [%s] on this Managed
- No plural attribute named '{}' and of element type '{}' in t
- ${name} is not a CollectionAttribute: ${attributeClass}
- ${name} is not a SetAttribute: ${attributeClass}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/12f13ce37b0ca2f3.
Report an issue: GitHub.