hibernate/hibernate-orm · error · IllegalArgumentException

Unable to locate persister: {}

Error message

Unable to locate persister: {}

What it means

MappingMetamodelImpl.getCollectionDescriptor(String role) looks up a collection persister by its role ('EntityName.collectionProperty'); a miss throws IllegalArgumentException('Unable to locate persister: ' + role). Roles are exact strings — FQNs of the property path, not of the class.

Source

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

		return jpaMetamodel.enumValue( enumType, enumValueName );
	}

	@Override
	public String getImportedName(String name) {
		final String qualifiedName = jpaMetamodel.qualifyImportableName( name );
		return qualifiedName == null ? name : qualifiedName;
	}

	@Override
	public void forEachCollectionDescriptor(Consumer<CollectionPersister> action) {
		collectionPersisterMap.values().forEach( action );
	}

	@Override
	public CollectionPersister getCollectionDescriptor(String role) {
		final var collectionPersister = collectionPersisterMap.get( role );
		if ( collectionPersister == null ) {
			throw new IllegalArgumentException( "Unable to locate persister: " + role );
		}
		return collectionPersister;
	}

	@Override
	public CollectionPersister getCollectionDescriptor(NavigableRole role) {
		throw new UnsupportedOperationException();
	}

	@Override
	public CollectionPersister findCollectionDescriptor(NavigableRole role) {
		throw new UnsupportedOperationException();
	}

	@Override
	public CollectionPersister findCollectionDescriptor(String role) {
		return collectionPersisterMap.get( role );
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use the exact role: registered entity name + '.' + collection attribute name (e.g. 'Customer.orders'), matching @Entity(name=...) if set
  2. Dump the real roles once and compare: sessionFactory.getRuntimeMetamodelImplementor().forEachCollectionDescriptor(p -> System.out.println(p.getRole()))
  3. Prefer a null-safe check (findCollectionDescriptor(role) == null) with a clear error listing valid roles

Example fix

// before
CollectionPersister p = mappingMetamodel.getCollectionDescriptor("com.acme.Customer.orders"); // FQN -> IllegalArgumentException

// after
CollectionPersister p = mappingMetamodel.getCollectionDescriptor("Customer.orders"); // entity name + property
Defensive patterns

Strategy: validation

Validate before calling

CollectionPersister findOrThrow(SessionFactory sf, String role) {
  MappingMetamodel mm = (MappingMetamodel) sf.getMetamodel();
  CollectionPersister p = mm.findCollectionDescriptor(role); // null-safe sibling
  if (p == null) {
    List<String> roles = new ArrayList<>();
    mm.forEachCollectionDescriptor(cp -> roles.add(cp.getRole()));
    throw new IllegalArgumentException("Unknown collection role '" + role + "'; registered: " + roles);
  }
  return p;
}

Try / catch

try {
  return mappingMetamodel.getCollectionDescriptor(role);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Unable to locate persister")) {
    // role strings are exact: 'EntityName.collectionProperty'; recheck against registered roles
    throw new IllegalArgumentException("Unknown collection role '" + role + "'", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Runtime APIs that take a collection role (cache configuration, filters, custom loaders, tooling): role 'Customer.orders' where the attribute is 'orderList', a typo, or the collection is mapped in another persistence unit; building the role from the class's fully-qualified name instead of the entity name.

Common situations: Second-level cache region configuration strings drift after renaming attributes or entities; code enumerates roles by hand; refactoring renames the collection property but config strings lag behind.

Related errors


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