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
- Query the concrete subclass that owns the table instead of going through the union of the hierarchy.
- Move shared columns to the mapped superclass / common tables so all branches expose them.
- Remove references to sibling-subclass columns from polymorphic queries (select/order only common attributes).
- 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
- In TABLE_PER_CLASS hierarchies, restrict polymorphic select/order-by to attributes mapped on the common root.
- Query concrete subclasses whenever subclass-specific columns are needed.
- When adding a subclass table, re-run polymorphic query tests to catch union-coverage gaps.
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
- unsupported temporal unit for CUBRID: " + unit
- Summarization is not supported by DBMS!
- Can't emulate offset clause in subquery
- Summarization is not supported by DBMS!
- unrecognized field: " + unit
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/26ae71c39e087609.
Report an issue: GitHub.