hibernate/hibernate-orm · error · UnknownTableReferenceException

Couldn't find table reference

Error message

Couldn't find table reference

What it means

For TABLE_PER_CLASS hierarchies, UnionSubclassEntityPersister.pruneForSubclasses replaces the root table reference with a generated subquery so only selected concrete tables are queried. It requires the incoming TableGroup to hold a reference to the root table; UnknownTableReferenceException('Couldn't find table reference') means the TableGroup was built without it, typically because a query path reused or built a table group for a subtype only.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java:421

		return tableName;
	}

	@Override
	protected boolean isIdentifierTable(String tableExpression) {
		return tableExpression.equals( getRootTableName() );
	}

	@Override
	public boolean hasMultipleTables() {
		// This could also just be true all the time...
		return isAbstract() || hasSubclasses();
	}

	@Override
	public void pruneForSubclasses(TableGroup tableGroup, Map<String, EntityNameUse> entityNameUses) {
		final var tableReference = (NamedTableReference) tableGroup.getTableReference( getRootTableName() );
		if ( tableReference == null ) {
			throw new UnknownTableReferenceException( getRootTableName(), "Couldn't find table reference" );
		}
		tableReference.setPrunedTableExpression( generateSubquery(
				entityNameUses,
				tableReference.getTableExpression()
		) );
	}

	@Override
	public void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) {
		for ( int i = 0; i < constraintOrderedTableNames.length; i++ ) {
			final String tableName = constraintOrderedTableNames[i];
			final int tablePosition = i;
			consumer.consume(
					tableName,
					() -> columnConsumer -> columnConsumer.accept(
							tableName,
							constraintOrderedKeyColumnNames[tablePosition],
							getIdentifierMapping()::getJdbcMapping

View on GitHub (pinned to fad1729dce)

Solutions

  1. Upgrade Hibernate - union-subclass pruning has had several fixes across 6.x/7.x
  2. Avoid treat() on TABLE_PER_CLASS hierarchies; select the concrete subtype directly instead
  3. Query the root entity with restrictions on root columns rather than treating to a subtype
  4. Build a minimal reproducer (query + mapping) and report it to Hibernate (HHH) if it fails on the latest version

Example fix

// before: treat() over a TABLE_PER_CLASS hierarchy
List<Vehicle> cars = session.createQuery(
    "select v from Vehicle v treat(v as Car c) where c.doorCount = :d", Vehicle.class)
    .getResultList();

// after: query the concrete subtype directly
List<Car> cars = session.createQuery(
    "from Car c where c.doorCount = :d", Car.class)
    .getResultList();
Defensive patterns

Strategy: fallback

Try / catch

try { results = query.getResultList(); } catch (UnknownTableReferenceException e) { /* union-subclass pruning failed: re-run the query against the concrete subtype */ }

Prevention

When it happens

Trigger: Polymorphic criteria/HQL with treat() against a TABLE_PER_CLASS hierarchy; loading through @Polymorphic interface references; fetch composition or entity-graph paths that construct subtype table groups for union persisters; known Hibernate defect paths in union-subclass pruning.

Common situations: treat(as: SubType) in HQL over union-subclass mappings; entity graphs or join fetches on TABLE_PER_CLASS hierarchies; upgrading Hibernate versions where pruning semantics changed.

Related errors


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