hibernate/hibernate-orm · error · IllegalArgumentException
${name} is not a SetAttribute: ${attributeClass}
Error message
${name} is not a SetAttribute: ${attributeClass} What it means
getSet(name)/getDeclaredSet(name) found the attribute but its concrete class is not a SetPersistentAttribute — typically it is a Bag (Collection), List, or Map attribute implementation. Hibernate includes the actual attribute class in the message.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java:537
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Set attributes
@Override
@SuppressWarnings("unchecked")
@Nonnull
public SetPersistentAttribute<? super J, ?> getSet(@Nonnull String name) {
final var attribute = findPluralAttribute( name );
basicSetCheck( attribute, name );
assert attribute != null;
return (SetPersistentAttribute<? super J, ?>) attribute;
}
private void basicSetCheck(PluralAttribute<? super J, ?, ?> attribute, String name) {
checkNotNull( "SetAttribute", attribute, name );
if ( ! SetPersistentAttribute.class.isAssignableFrom( attribute.getClass() ) ) {
throw new IllegalArgumentException( name + " is not a SetAttribute: " + attribute.getClass() );
}
}
@Override
@SuppressWarnings( "unchecked")
@Nonnull
public SetPersistentAttribute<J, ?> getDeclaredSet(@Nonnull String name) {
final var attribute = findDeclaredPluralAttribute( name );
basicSetCheck( attribute, name );
assert attribute != null;
return (SetPersistentAttribute<J, ?>) attribute;
}
@Override
@SuppressWarnings("unchecked")
@Nonnull
public <E> SetAttribute<? super J, E> getSet(@Nonnull String name, @Nonnull Class<E> elementType) {
final var attribute = findPluralAttribute( name );View on GitHub (pinned to fad1729dce)
Solutions
- Use getList/getCollection/getMap according to the actual declaration
- Change the entity field to java.util.Set if set semantics are wanted (and re-check equals/hashCode of the element type)
- Derive the accessor dynamically from attribute.getCollectionType()
Example fix
// before
SetPersistentAttribute<Post, String> tags = postType.getSet("tags"); // List<String> field -> throws
// after
ListPersistentAttribute<Post, String> tags = postType.getList("tags");
// or change field: Set<String> tags; Defensive patterns
Strategy: type-guard
Validate before calling
var attr = StreamSupport.stream(type.getAttributes().spliterator(), false)
.filter(a -> a.getName().equals(name)).findFirst().orElse(null);
if (!(attr instanceof org.hibernate.metamodel.model.domain.SetPersistentAttribute)) {
throw new IllegalArgumentException(name + " is not a Set on " + type.getTypeName());
} Type guard
static boolean isSetAttr(ManagedType<?> type, String name) {
for (Attribute<?,?> a : type.getAttributes()) {
if (a.getName().equals(name)
&& a instanceof org.hibernate.metamodel.model.domain.SetPersistentAttribute) return true;
}
return false;
} Try / catch
try {
return type.getSet(name);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("is not a SetAttribute")) {
return null; // or route to getList/getCollection based on real kind
}
throw e;
} Prevention
- Set accessors only work on Set-mapped fields
- When refactoring collection kinds, grep for getSet( call sites
- Log the actual attributeClass from the exception to pick the correct accessor
When it happens
Trigger: Calling getSet("tags") on a field declared as Collection<String>, List<String>, or Map<...>. Set semantics (unique elements) only exist for Set/PersistentSet mappings.
Common situations: Field declared as List or Collection while the code assumes a Set; switching collection types during refactoring without updating metamodel accessors.
Related errors
- No plural attribute named '{}' and of element type '{}' in t
- ${name} is not a ListAttribute: ${attributeClass}
- ${name} is not a MapAttribute: ${attributeClass}
- Attribute '%s.%s' of type '%s' is annotated '@Bag' (bags are
- Attribute [%s#%s : %s] not castable to requested type [%s]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/14723ec63fc603f0.
Report an issue: GitHub.