Auditing fails at startup — "Couldn't find PersistentEntity for type ?" — for entities with nested generic collections (Spring Data 2026.0 / commons 4.1)
Affected versions
- Spring Boot 4.1.0
- Spring Data BOM 2026.0.0 → spring-data-commons 4.1.0, spring-data-mongodb 4.1.0, spring-data-rest 5.1.0
- Reproduces on Java 21 and 25.
- Works with Spring Data BOM 2025.1.6 (commons 4.0.6), keeping Boot 4.1.0.
Summary
When an audited/REST-exposed MongoDB entity has a nested generic collection property
(e.g. Map<String, Map<String, X>>), building the auditing metadata at startup fails with
MappingException: Couldn't find PersistentEntity for type ?. The auditing bean walks the
property paths of every persistent entity, a raw java.util.Map/List gets registered as
a persistent entity, and resolving its wildcard element type throws.
Minimal reproducer
spring441-auditing-repro.zip
Full project attached; the entire model is four files:
@Document("item")
class Item {
@Id String id;
Map<String, Map<String, Cell>> values; // nested generic map — the trigger
}
class Cell {
Object value;
}
@RepositoryRestResource
interface ItemRepository extends MongoRepository<Item, String> {}
@SpringBootApplication
@EnableMongoRepositories
@EnableMongoAuditing
class ReproApplication { public static void main(String[] a){ SpringApplication.run(ReproApplication.class,a);} }
pom.xml: spring-boot-starter-parent 4.1.0, deps spring-boot-starter-data-mongodb +
spring-boot-starter-data-rest. ./mvnw spring-boot:run crashes; pinning
<spring-data-bom.version>2025.1.6</spring-data-bom.version> fixes it.
No auditing annotation on Item is required — the metadata builder walks every entity.
Without Spring Data REST it manifests identically via @EnableMongoAuditing's
IsNewAwareAuditingHandler when some entity carries auditing annotations.
Stack trace
BeanCreationException: 'auditableBeanWrapperFactory' … Failed to instantiate
[org.springframework.data.auditing.AuditableBeanWrapperFactory]:
Factory method 'auditableBeanWrapperFactory' threw exception: Couldn't find PersistentEntity for type ?
Caused by: org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type ?
at o.s.d.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:121)
at o.s.d.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:231)
at o.s.d.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:168)
at o.s.d.mapping.context.AbstractMappingContext.doFindPersistentPropertyPaths(AbstractMappingContext.java:376)
at o.s.d.mapping.context.AbstractMappingContext.findPersistentPropertyPaths(AbstractMappingContext.java:360)
at o.s.d.auditing.MappingAuditableBeanWrapperFactory$MappingAuditingMetadata.findPropertyPaths(…:162)
at o.s.d.auditing.MappingAuditableBeanWrapperFactory$MappingAuditingMetadata.<init>(…:136)
at o.s.d.auditing.MappingAuditableBeanWrapperFactory.<init>(…:76) // iterates every entity
at o.s.d.rest.webmvc.config.RepositoryRestMvcConfiguration.auditableBeanWrapperFactory(…:863)
Root cause
Diffing the -sources.jar of commons 4.0.6 vs 4.1.0, the one behaviourally relevant
change in the mapping layer is that
AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(...) dropped the
early transient guard:
P property = createPersistentProperty(input, entity, simpleTypeHolder);
if (property.isTransient()) { // <-- present in 4.0.6, REMOVED in 4.1.0
return;
}
...
entity.addPersistentProperty(property);
together with the new transient-property tracking added to BasicPersistentEntity
(transientProperties, transientPropertyCache, getTransientProperty, isTransient(String))
— i.e. the @Transient-in-constructors feature (#2942) from the 2026.0 mapping-layer rewrite.
The side effect: a raw java.util.Map/List now ends up registered as a persistent entity,
and MappingAuditableBeanWrapperFactory (invoked from both
IsNewAwareAuditingHandler.from(...) and Spring Data REST's auditableBeanWrapperFactory)
walks it — TypeInformation.of(Map.class).getActualType() is the wildcard ?, so
getRequiredPersistentEntity(?) throws.
This is functionally the same failure as the long-fixed #3056 (fixed in 3.2.4), reintroduced by
the 4.1 rewrite.
Workaround
Pin Spring Data back one train while keeping Boot 4.1.0:
<properties>
<spring-data-bom.version>2025.1.6</spring-data-bom.version>
</properties>
Auditing fails at startup — "Couldn't find PersistentEntity for type ?" — for entities with nested generic collections (Spring Data 2026.0 / commons 4.1)
Affected versions
Summary
When an audited/REST-exposed MongoDB entity has a nested generic collection property
(e.g.
Map<String, Map<String, X>>), building the auditing metadata at startup fails withMappingException: Couldn't find PersistentEntity for type ?. The auditing bean walks theproperty paths of every persistent entity, a raw
java.util.Map/Listgets registered asa persistent entity, and resolving its wildcard element type throws.
Minimal reproducer
spring441-auditing-repro.zip
Full project attached; the entire model is four files:
pom.xml:spring-boot-starter-parent4.1.0, depsspring-boot-starter-data-mongodb+spring-boot-starter-data-rest../mvnw spring-boot:runcrashes; pinning<spring-data-bom.version>2025.1.6</spring-data-bom.version>fixes it.Stack trace
Root cause
Diffing the
-sources.jarof commons 4.0.6 vs 4.1.0, the one behaviourally relevantchange in the mapping layer is that
AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(...)dropped theearly transient guard:
together with the new transient-property tracking added to
BasicPersistentEntity(
transientProperties,transientPropertyCache,getTransientProperty,isTransient(String))— i.e. the
@Transient-in-constructors feature (#2942) from the 2026.0 mapping-layer rewrite.The side effect: a raw
java.util.Map/Listnow ends up registered as a persistent entity,and
MappingAuditableBeanWrapperFactory(invoked from bothIsNewAwareAuditingHandler.from(...)and Spring Data REST'sauditableBeanWrapperFactory)walks it —
TypeInformation.of(Map.class).getActualType()is the wildcard?, sogetRequiredPersistentEntity(?)throws.This is functionally the same failure as the long-fixed #3056 (fixed in 3.2.4), reintroduced by
the 4.1 rewrite.
Workaround
Pin Spring Data back one train while keeping Boot 4.1.0: