hibernate/hibernate-orm · error · UnsupportedOperationException

Can't emulate '" + tableGroupJoin.getJoinType().getText() +

Error message

Can't emulate '" + tableGroupJoin.getJoinType().getText() + "join' in a DB2 recursive query part

What it means

UnionTableReference is the from-element covering the unioned tables of a TABLE_PER_CLASS (union-subclass) hierarchy; it answers resolveTableReference via hasTableExpression only for the table names included in the union set and throws UnknownTableReferenceException for anything else. The error means the requested table belongs to a sibling branch of the hierarchy (or is entirely unrelated) and is not part of this union reference.

Source

Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java:117

				if ( tableJoin.getPredicate() != null && !tableJoin.getPredicate().isEmpty() ) {
					addAdditionalWherePredicate( tableJoin.getPredicate() );
				}
			}
		}
		else {
			super.renderTableReferenceJoins( tableGroup, lockMode, swappedJoinIndex, forceLeftJoin );
		}
	}

	@Override
	protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGroupJoin> tableGroupJoinCollector) {
		if ( isInRecursiveQueryPart() ) {
			switch ( tableGroupJoin.getJoinType() ) {
				case CROSS:
				case INNER:
					break;
				default:
					throw new UnsupportedOperationException( "Can't emulate '" + tableGroupJoin.getJoinType().getText() + "join' in a DB2 recursive query part" );
			}
			appendSql( COMMA_SEPARATOR_CHAR );

			renderJoinedTableGroup( tableGroupJoin, null, tableGroupJoinCollector );
			if ( tableGroupJoin.getPredicate() != null && !tableGroupJoin.getPredicate().isEmpty() ) {
				addAdditionalWherePredicate( tableGroupJoin.getPredicate() );
			}
		}
		else {
			super.renderTableGroupJoin( tableGroupJoin, tableGroupJoinCollector );
		}
	}

	@Override
	protected void renderExpressionAsClauseItem(Expression expression) {
		if ( expression instanceof Predicate && getDB2Version().isBefore( 11 ) ) {
			super.renderExpressionAsClauseItem( expression );
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Query the concrete subclass that owns the table instead of going through the union of the hierarchy.
  2. Move shared columns to the mapped superclass / common tables so all branches expose them.
  3. Remove references to sibling-subclass columns from polymorphic queries (select/order only common attributes).
  4. Verify union table registration after inheritance mapping changes; upgrade Hibernate for union-resolution fixes.

Example fix

// before: subclass-specific column through the union hierarchy
"select e from Employee e order by e.contractDetailsClauses" // column only on ContractEmployee

// after: query the concrete subclass
"select c from ContractEmployee c order by c.contractDetailsClauses"
Defensive patterns

Strategy: validation

Validate before calling

// Before polymorphic union queries: ensure only hierarchy-common attributes are referenced
Set<String> commonAttributes = superclassAttributes( Employee.class );
boolean onlyCommon = referencedPaths.stream().allMatch( commonAttributes::contains );
if ( !onlyCommon ) {
    // narrow the query to the concrete subclass owning those columns
    Class<?> concrete = owningSubclassFor( referencedPaths );
}

Try / catch

try {
    return em.createQuery(hql, type).getResultList();
} catch ( UnknownTableReferenceException e ) {
    // sibling-subclass table requested through the union: query the concrete subclass
    return em.createQuery(narrowToConcreteSubclass(hql, e.getTableExpression()), type).getResultList();
}

Prevention

When it happens

Trigger: Polymorphic queries over a union-subclass hierarchy that reference a table specific to one subclass (e.g. ordering or selecting SubA-only columns while the union path routes through SubB's branch); subclass table names not registered in the union reference after mapping edits; cross-hierarchy table name collisions.

Common situations: TABLE_PER_CLASS inheritance with subclass-specific tables queried through the superclass or a sibling subclass; adding a new subclass/table without rebuilding mappings in tests; dialect/translator paths resolving subclass tables per union branch.

Related errors


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