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;
	}

	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Upgrade Hibernate - pruning arithmetic for joined-subclass persisters has had multiple fixes
  2. Rewrite the query to select the concrete subtype directly instead of using treat()/polymorphic pruning
  3. Temporarily remove filters/treat() to confirm they trigger the path
  4. 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

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


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