{"record":{"id":"4101a5c3be225c93","repo":"hibernate/hibernate-orm","slug":"mutating-table-reference-should-be-handled-by-the","errorCode":null,"errorMessage":"Mutating table reference should be handled by the statement visitation","messagePattern":"Mutating table reference should be handled by the statement visitation","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/model/ast/MutatingTableReference.java","lineNumber":54,"sourceCode":"\n\t@Override\n\tpublic String getIdentificationVariable() {\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic String getTableId() {\n\t\treturn getTableName();\n\t}\n\n\t@Override\n\tpublic boolean isOptional() {\n\t\treturn tableMapping.isOptional();\n\t}\n\n\t@Override\n\tpublic void accept(SqlAstWalker sqlTreeWalker) {\n\t\tthrow new UnsupportedOperationException( \"Mutating table reference should be handled by the statement visitation\" );\n\t}\n\n\t@Override\n\tpublic Boolean visitAffectedTableNames(Function<String, Boolean> nameCollector) {\n\t\treturn nameCollector.apply( getTableName() );\n\t}\n\n\t@Override\n\tpublic TableReference resolveTableReference(\n\t\t\tNavigablePath navigablePath,\n\t\t\tString tableExpression) {\n\t\tif ( getTableName().equals( tableExpression ) ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tthrow new IllegalArgumentException(\n\t\t\t\tString.format(\n\t\t\t\t\t\tLocale.ROOT,","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/model/ast/MutatingTableReference.java#L36-L72","documentation":"MutatingTableReference is the table reference inside insert/update/delete statements. Its accept() deliberately throws UnsupportedOperationException because mutation rendering must walk the whole statement (TableInsert/TableUpdate/TableDelete) so the walker sees parameters, optional-table handling and returning clauses in context. A generic SqlAstWalker cannot render a mutating table reference in isolation.","triggerScenarios":"Passing a MutatingTableReference to a generic AST walker - e.g. utilities that call accept() on every TableReference found in an AST that mixes selects and mutations; reusing a select-statement walker or analyzer over mutation statements.","commonSituations":"Custom dialect statement emitters and SQL renderers; AST analysis/visitation utilities that iterate table references without special-casing mutation statements; code written against select-only ASTs later pointed at mutations.","solutions":["Visit the containing statement instead: tableInsert.accept(walker) / tableUpdate.accept(walker) - statement visitation handles its mutating table reference","Special-case MutatingTableReference in your walker and route to the mutation statement","Use visitAffectedTableNames(...) (already implemented) when you only need the affected table names","Never route mutation ASTs through select-statement walkers"],"exampleFix":"// before\nmutatingTableReference.accept( genericWalker ); // throws\n\n// after\nmutationStatement.accept( walker ); // TableInsert/TableUpdate/TableDelete drives its own table reference","handlingStrategy":"validation","validationCode":"if ( ref instanceof MutatingTableReference ) {\n    mutationStatement.accept( walker ); // statement drives its own table reference\n} else {\n    ref.accept( walker );\n}","typeGuard":"boolean isMutatingReference(TableReference ref) {\n    return ref instanceof MutatingTableReference;\n}","tryCatchPattern":null,"preventionTips":["Never call accept() on a MutatingTableReference - always visit the containing mutation statement","Use visitAffectedTableNames() when only table names are needed","Keep custom walkers separate for select vs mutation ASTs"],"tags":["hibernate","orm","sql-ast","mutation","visitor","internal-api"],"backgroundTag":"ast-visitor-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}