hibernate/hibernate-orm · critical · UnsupportedMappingException

Unknown collection: {}

Error message

Unknown collection: {}

What it means

PluralAttributeBuilder.build builds the JPA PluralAttribute for a mapped collection attribute. After strict matching (exact Map/List/Collection) and loose matching (arrays, then assignable Map/Set/List/Collection), a declared Java collection type that falls through every branch throws UnsupportedMappingException('Unknown collection: ' + javaType) at bootstrap. In practice that means a type that is not a Map/Set/List/Collection or array — most commonly a type implementing only Iterable.

Source

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

		//apply loose rules
		if ( javaClass.isArray() ) {
			return new ListAttributeImpl( builder );
		}

		if ( Map.class.isAssignableFrom( javaClass ) ) {
			return new MapAttributeImpl( builder );
		}
		else if ( Set.class.isAssignableFrom( javaClass ) ) {
			return new SetAttributeImpl( builder );
		}
		else if ( List.class.isAssignableFrom( javaClass ) ) {
			return new ListAttributeImpl( builder );
		}
		else if ( Collection.class.isAssignableFrom( javaClass ) ) {
			return new BagAttributeImpl( builder );
		}

		throw new UnsupportedMappingException( "Unknown collection: " + attributeJtd.getJavaType() );
	}

	private static SimpleDomainType<?> determineListIndexOrMapKeyType(
			PluralAttributeMetadata<?,?,?> attributeMetadata,
			MetadataContext metadataContext) {
		final var javaType = attributeMetadata.getJavaType();
		if ( Map.class.isAssignableFrom( javaType ) ) {
			return (SimpleDomainType<?>)
					determineSimpleType( attributeMetadata.getMapKeyValueContext(), metadataContext );
		}

		if ( List.class.isAssignableFrom( javaType ) || javaType.isArray() ) {
			return metadataContext.getTypeConfiguration().getBasicTypeRegistry()
					.getRegisteredType( Integer.class );
		}

		return null;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Declare the attribute as one of java.util.Collection, List, Set, or Map (or a primitive array) — e.g. change Iterable<Order> to List<Order>
  2. For custom collection wrappers, expose a standard JDK collection type on the mapped property and adapt elsewhere
  3. If the type was never meant to be a persistent collection, remove the association annotation

Example fix

// before
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private Iterable<OrderLine> lines; // UnsupportedMappingException: Unknown collection

// after
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderLine> lines;
Defensive patterns

Strategy: validation

Validate before calling

// Startup scan: reject association attributes whose Java type is not a mappable collection
for (Class<?> c : scannedEntityClasses) {
  for (java.lang.reflect.Field f : c.getDeclaredFields()) {
    boolean isAssociation = f.isAnnotationPresent(OneToMany.class)
        || f.isAnnotationPresent(ManyToMany.class)
        || f.isAnnotationPresent(ElementCollection.class);
    if (isAssociation) {
      Class<?> t = f.getType();
      boolean ok = t.isArray() || Map.class.isAssignableFrom(t) || Collection.class.isAssignableFrom(t);
      if (!ok) {
        throw new IllegalStateException("Association field " + f
            + " must be Map/Set/List/Collection/array, not " + t.getName());
      }
    }
  }
}

Type guard

static boolean isMappableCollectionType(Class<?> t) {
  return t.isArray() || Map.class.isAssignableFrom(t) || Collection.class.isAssignableFrom(t);
}

Prevention

When it happens

Trigger: An @OneToMany/@ManyToMany/@ElementCollection attribute declared as Iterable<T>, Queue handled? (no — Queue extends Collection so it matches Bag), but Iterable<T>, or a custom collection class implementing only Iterable; an attribute whose getter returns a non-JDK-collection type due to wrong mapping on the wrong field.

Common situations: Domain models using Iterable for read models then annotated as associations; custom Bag/List abstractions that only extend Iterable; IDE-generated fields typed Iterable; Kotlin/Scala collection types not bridged to java.util types in mappings.

Related errors


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