hibernate/hibernate-orm · error · AnnotationException
Collection '{}' annotated '@NotFound' is not a '@ManyToMany'
Error message
Collection '{}' annotated '@NotFound' is not a '@ManyToMany' association What it means
In this Hibernate version, @NotFound on a collection-valued association is only supported for @ManyToMany. CollectionBinder.notFoundAction throws this AnnotationException when @NotFound is present on a collection property but the @ManyToMany annotation is absent (e.g. a @OneToMany or an un-annotated collection).
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java:386
private static void addDefinition(
IdentifierGeneratorDefinition definition,
Map<String, IdentifierGeneratorDefinition> availableGenerators) {
final String definitionName = definition.getName();
if ( !definitionName.isEmpty() ) {
availableGenerators.put( definitionName, definition );
}
}
private static NotFoundAction notFoundAction(
PropertyHolder propertyHolder,
PropertyData inferredData,
MemberDetails property,
ManyToMany manyToManyAnn,
ModelsContext sourceModelContext) {
final var notFound = property.getAnnotationUsage( NotFound.class, sourceModelContext );
if ( notFound != null ) {
if ( manyToManyAnn == null ) {
throw new AnnotationException( "Collection '" + getPath(propertyHolder, inferredData)
+ "' annotated '@NotFound' is not a '@ManyToMany' association" );
}
return notFound.action();
}
else {
return null;
}
}
private static AnnotatedJoinColumns mapKeyJoinColumns(
PropertyHolder propertyHolder,
PropertyData inferredData,
EntityBinder entityBinder,
MetadataBuildingContext context,
MemberDetails property) {
return buildJoinColumnsWithDefaultColumnSuffix(
mapKeyJoinColumnAnnotations( property, context ),
null,View on GitHub (pinned to fad1729dce)
Solutions
- Remove @NotFound from the collection property
- If not-found tolerance is truly required, model the association as @ManyToMany and keep @NotFound there
- For a @OneToMany, handle missing rows in application code or fix the data so referenced rows always exist
Example fix
// before
@Entity
class PurchaseOrder {
@OneToMany(mappedBy = "order")
@NotFound(action = NotFoundAction.IGNORE) // error: only @ManyToMany supports @NotFound
List<OrderLine> lines;
}
// after
@Entity
class PurchaseOrder {
@OneToMany(mappedBy = "order")
List<OrderLine> lines;
} Defensive patterns
Strategy: validation
Validate before calling
// Scan annotated classes before boot: @NotFound on a collection that is not @ManyToMany
static void checkNotFoundOnlyOnManyToMany(Class<?>... entities) {
for ( Class<?> c : entities ) {
for ( Field f : c.getDeclaredFields() ) {
if ( f.isAnnotationPresent( NotFound.class )
&& !f.isAnnotationPresent( ManyToMany.class ) ) {
throw new IllegalStateException( "@NotFound on non-@ManyToMany collection: "
+ c.getName() + "." + f.getName() );
}
}
}
} Prevention
- Reserve @NotFound for @ManyToOne/@OneToOne and @ManyToMany - never @OneToMany collections
- When upgrading Hibernate, grep the codebase for @NotFound usages on collections and remove them
- Fix referential integrity in data instead of relying on not-found tolerance for collections
When it happens
Trigger: A collection property carries @NotFound(action = ...) but the manyToManyAnn parameter passed to notFoundAction(...) is null - i.e. the property is a @OneToMany or has no to-many annotation at all.
Common situations: Migrating from older Hibernate versions where @NotFound on @OneToMany was silently tolerated or handled; copying @ManyToOne/@NotFound patterns onto collections; expecting lazy not-found semantics on a one-to-many collection.
Related errors
- Property '{}' is annotated both '@OneToMany' and '@ManyToMan
- @SoftDelete cannot be applied to @OneToMany - {}.{}
- Collection '{}' is the unowned side of a bidirectional '@Man
- Property '%s.%s' is not a collection and may not be a '@OneT
- Property '${property}' uses *-to-many mapping with mappedBy
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/1548c2cb5f47a0d9.
Report an issue: GitHub.