hibernate/hibernate-orm · error · MappingException
Could not instantiate comparator class [{}] for collection {
Error message
Could not instantiate comparator class [{}] for collection {} What it means
Sorted collections configured with an explicit comparator (hbm sort="comparatorClass" or @SortComparator) are instantiated reflectively via getConstructor().newInstance(); any failure — missing public no-arg constructor, non-public class, or a constructor that throws — aborts mapping validation with this MappingException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/mapping/Collection.java:256
return collectionTable;
}
public void setCollectionTable(Table table) {
this.collectionTable = table;
}
public boolean isSorted() {
return sorted;
}
public Comparator<?> getComparator() {
if ( comparator == null && comparatorClassName != null ) {
final var clazz = classForName( Comparator.class, comparatorClassName, getBootstrapContext() );
try {
comparator = clazz.getConstructor().newInstance();
}
catch (Exception e) {
throw new MappingException( "Could not instantiate comparator class ["
+ comparatorClassName + "] for collection " + getRole() );
}
}
return comparator;
}
@Override
public boolean isLazy() {
return lazy;
}
@Override
public void setLazy(boolean lazy) {
this.lazy = lazy;
}
public String getRole() {
return role;View on GitHub (pinned to fad1729dce)
Solutions
- Add a public no-arg constructor to the comparator class and keep the class public.
- Never throw from the comparator constructor; initialize lazily inside compare().
- For natural ordering use @SortNatural (or omit the comparator) instead.
Example fix
// before
public class InvoiceComparator implements Comparator<Invoice> {
public InvoiceComparator(SortService svc) { ... } // only constructor
}
// after
public class InvoiceComparator implements Comparator<Invoice> {
public InvoiceComparator() { }
@Override
public int compare(Invoice a, Invoice b) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// fail fast before building the SessionFactory Class<? extends Comparator<?>> c = MyComparator.class; c.getConstructor().newInstance(); // must not throw
Prevention
- Always give comparators a public no-arg constructor
- Prefer @SortNatural for natural ordering
- Unit-test comparator instantiation as part of mapping tests
When it happens
Trigger: @SortComparator(InvoiceComparator.class) where the comparator has only parameterized constructors or throws from its no-arg constructor; hbm sort FQCN resolving to a non-public class; comparator constructor depending on injected or uninitialized state.
Common situations: Comparators written as DI beans or with required constructor arguments; utility comparators with hidden constructors; refactoring introducing stateful comparators.
Related errors
- Could not instantiate event listener '{}'
- Unable to instantiate StatementObserver - {}
- Could not instantiate named strategy class [{}]
- Could not instantiate named strategy class [%s]
- Unable to instantiate specified auto SessionEventListener: {
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/fe7e2b9a01fdf2c0.
Report an issue: GitHub.