hibernate/hibernate-orm · error · IllegalArgumentException

${name} is not a ListAttribute: ${attributeClass}

Error message

${name} is not a ListAttribute: ${attributeClass}

What it means

getList(name)/getDeclaredList(name) found the attribute but it is not a ListPersistentAttribute — it is a bag (plain Collection), Set, or Map attribute. The message prints the concrete attribute class so you can tell which kind it is.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java:591


	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// List attributes

	@Override
	@SuppressWarnings("unchecked")
	@Nonnull
	public ListPersistentAttribute<? super J, ?> getList(@Nonnull String name) {
		final var attribute = findPluralAttribute( name );
		basicListCheck( attribute, name );
		assert attribute != null;
		return (ListPersistentAttribute<? super J, ?>) attribute;
	}

	private void basicListCheck(PluralAttribute<? super J, ?, ?> attribute, String name) {
		checkNotNull( "ListAttribute", attribute, name );
		if ( ! ListPersistentAttribute.class.isAssignableFrom( attribute.getClass() ) ) {
			throw new IllegalArgumentException( name + " is not a ListAttribute: " + attribute.getClass() );
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	@Nonnull
	public ListPersistentAttribute<J, ?> getDeclaredList(@Nonnull String name) {
		final var attribute = findDeclaredPluralAttribute( name );
		basicListCheck( attribute, name );
		assert attribute != null;
		return (ListPersistentAttribute<J, ?>) attribute;
	}

	@Override
	@SuppressWarnings("unchecked")
	@Nonnull
	public <E> ListAttribute<? super J, E> getList(@Nonnull String name, @Nonnull Class<E> elementType) {
		final var attribute = findPluralAttribute( name );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Declare the field as java.util.List (add @OrderColumn if an index column is needed) when list semantics are intended
  2. Or call getCollection(name) for bag-mapped Collection fields
  3. Check the message's attributeClass to confirm the real mapping kind

Example fix

// before
ListPersistentAttribute<Order, Line> lines = orderType.getList("lines"); // Collection<Line> bag -> throws

// after
// either: private List<Line> lines;  (+ @OrderColumn if needed)
// or:    CollectionAttribute<Order, Line> lines = orderType.getCollection("lines");
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.ListPersistentAttribute)) {
    throw new IllegalArgumentException(name + " is not a List on " + type.getTypeName());
}

Type guard

static boolean isListAttr(ManagedType<?> type, String name) {
    for (Attribute<?,?> a : type.getAttributes()) {
        if (a.getName().equals(name)
                && a instanceof org.hibernate.metamodel.model.domain.ListPersistentAttribute) return true;
    }
    return false;
}

Try / catch

try {
    return type.getList(name);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("is not a ListAttribute")) {
        // Collection-mapped bag: use getCollection(name)
        return type.getCollection(name);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getList("lines") when the field is declared as Collection<OrderLine> (mapped as a bag, not a list) or as a Set. In JPA, Collection fields map to bags unless declared List; only List fields support ordered/indexed semantics.

Common situations: Declaring the field as Collection and expecting list behavior; JPA bag-vs-list distinction surprises (bags allow duplicates and no index; @OrderColumn requires List).

Related errors


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