hibernate/hibernate-orm · error · UnsupportedOperationException

removeTableGroupJoin not supported by %s

Error message

removeTableGroupJoin not supported by %s

What it means

removeTableGroupJoin(TableGroupJoin) is a default method on the TableGroup interface that throws UnsupportedOperationException naming the concrete class. Only groups that extend AbstractTableGroup (or delegate through DelegatingTableGroup) actually implement removal. Calling it on any other TableGroup implementation - a QueryPartTableGroup, a custom hand-rolled group - fails.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroup.java:58

	List<TableGroupJoin> getTableGroupJoins();

	List<TableGroupJoin> getNestedTableGroupJoins();

	boolean canUseInnerJoins();

	default boolean isLateral() {
		return false;
	}

	void addTableGroupJoin(TableGroupJoin join);

	/**
	 * Removes the given table group join from this group's joins. No-op if not
	 * present. Default implementation is unsupported; concrete groups override.
	 */
	default void removeTableGroupJoin(TableGroupJoin join) {
		throw new UnsupportedOperationException(
				"removeTableGroupJoin not supported by " + getClass().getName() );
	}

	/**
	 * Adds the given table group join before a join as found via the given navigable path.
	 */
	void prependTableGroupJoin(NavigablePath navigablePath, TableGroupJoin join);

	/**
	 * A nested table group join is a join against a table group,
	 * that is ensured to be joined against the primary table reference and table reference joins in isolation,
	 * prior to doing other table group joins e.g.
	 *
	 * <code>
	 * select *
	 * from entity1 e
	 * left join (
	 * 	 collection_table c1

View on GitHub (pinned to fad1729dce)

Solutions

  1. Extend AbstractTableGroup (or wrap with DelegatingTableGroup) so removeTableGroupJoin works out of the box
  2. Override removeTableGroupJoin in the custom TableGroup class named in the exception message
  3. Restructure the query/mapping so join removal is not needed (e.g. re-check @NotFound associations that trigger rewriting)
  4. Update custom dialect/extension code to the Hibernate version that added the method

Example fix

// before
class MyTableGroup implements TableGroup { /* no removeTableGroupJoin */ }

// after
class MyTableGroup extends AbstractTableGroup {
    @Override
    public void removeTableGroupJoin(TableGroupJoin join) {
        tableGroupJoins.remove( join );
    }
}
Defensive patterns

Strategy: validation

Validate before calling

boolean supportsJoinRemoval(TableGroup group) {
    return group instanceof AbstractTableGroup || group instanceof DelegatingTableGroup;
}

Try / catch

try {
    group.removeTableGroupJoin( join );
} catch ( UnsupportedOperationException e ) {
    if ( e.getMessage() != null && e.getMessage().startsWith( "removeTableGroupJoin not supported" ) ) {
        // rebuild the table group instead of mutating it
    } else { throw e; }
}

Prevention

When it happens

Trigger: SQM-to-SQL AST translation paths that rewrite or remove joins (not-found/optional association handling, criteria query rewrites, join de-duplication) invoke removeTableGroupJoin on the target group; the throw happens when that group's class never overrode the method. Custom TableGroup implementations returned from custom TableGroupProducers hit the same wall.

Common situations: Upgrading Hibernate to a version that introduced this interface method while a custom TableGroup subclass was not updated; join removal being triggered on non-standard table groups (CTE/query-part/union groups) by @NotFound or fetch rewriting; custom query translators or test harnesses manipulating table groups.

Related errors


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