hibernate/hibernate-orm · error · IllegalArgumentException
Given subclass table number is outside expected range [%s] a
Error message
Given subclass table number is outside expected range [%s] as defined by subclassTableNameClosure/subclassClosure
What it means
getSubclassNameClosureBySubclassTable translates a subclass table number into the class names mapped to that table; it is used when Hibernate prunes/polymorphically restricts a TableGroup for a JOINED hierarchy (filters, treat(), entity-name uses). IllegalArgumentException indicates the passed table number, minus getTableSpan(), indexes past the end of subclassNamesBySubclassTable - a caller used a table number beyond the known subclass tables, normally an internal defect or a query path the pruning code did not expect.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java:939
if ( treatAsDeclarations != null && !treatAsDeclarations.isEmpty() ) {
final var inclusionSubclassNameClosure =
getSubclassNameClosureBySubclassTable( subclassTableNumber );
// NOTE: we assume the entire hierarchy is joined-subclass here
for ( String subclassName : treatAsDeclarations ) {
for ( String inclusionSubclassName : inclusionSubclassNameClosure ) {
if ( inclusionSubclassName.equals( subclassName ) ) {
return true;
}
}
}
}
return false;
}
private String[] getSubclassNameClosureBySubclassTable(int subclassTableNumber) {
final int index = subclassTableNumber - getTableSpan();
if ( index >= subclassNamesBySubclassTable.length ) {
throw new IllegalArgumentException(
"Given subclass table number is outside expected range [" + (subclassNamesBySubclassTable.length -1)
+ "] as defined by subclassTableNameClosure/subclassClosure"
);
}
return subclassNamesBySubclassTable[index];
}
@Override
public String[] getConstraintOrderedTableNameClosure() {
return constraintOrderedTableNames;
}
@Override
public String[][] getConstraintOrderedTableKeyColumnClosure() {
return constraintOrderedKeyColumnNames;
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Upgrade Hibernate - pruning arithmetic for joined-subclass persisters has had multiple fixes
- Rewrite the query to select the concrete subtype directly instead of using treat()/polymorphic pruning
- Temporarily remove filters/treat() to confirm they trigger the path
- If it reproduces on the latest version, file a Hibernate (HHH) issue with the query and mapping
Defensive patterns
Strategy: validation
Try / catch
try { results = query.getResultList(); } catch (IllegalArgumentException e) { /* treat()/filter pruning over JOINED hierarchy unsupported on this version: fall back to selecting the concrete subtype */ } Prevention
- Prefer selecting concrete subtypes over treat() on JOINED hierarchies
- Keep Hibernate patched - pruning arithmetic fixes land regularly
- Add query-layer tests for every polymorphic query with filters or treat()
When it happens
Trigger: Polymorphic criteria/HQL with treat() over a JOINED hierarchy; @Filter/@FilterDef applying entity-name-use pruning; loading through @Polymorphic/interface references; any path where the table-span arithmetic at query time diverges from the array built at construction time.
Common situations: treat(as: SubType) in HQL/Criteria on JOINED inheritance; soft-delete or tenant filters on joined hierarchies; upgrading between Hibernate 6.4/6.6/7.x where EntityNameUse pruning internals changed.
Related errors
- Discriminator formulas on joined inheritance hierarchies not
- Could not format discriminator value to SQL string
- optimistic-lock=all|dirty not supported for joined-subclass
- Encountered 'subclass table index' [%s] was outside expected
- Was unable to locate subclass table [%s] in 'subclassTableNa
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/9771ae229c9cd66a.
Report an issue: GitHub.