hibernate/hibernate-orm · error · InterpretationException
Couldn't generate CTE name for base name [%s] after %d tries
Error message
Couldn't generate CTE name for base name [%s] after %d tries
What it means
Thrown during SQM-to-SQL translation when Hibernate must invent a SQL-level name for a CTE and every candidate collides. getCteName() derives a base name from the SqmCteTable label (or a synthetic 'cte<n>'), and generateCteName() tries baseName, then baseName_0 through baseName_3 (5 tries) against cteNameMapping; if all 5 are taken, translation aborts with an InterpretationException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java:1888
// route the CTE name through the IdentifierHelper so it gets the same quoting
// treatment (reserved words, global/auto quoting) as any other identifier
final String cteName = getSessionFactory().getJdbcServices().getJdbcEnvironment()
.getIdentifierHelper().toIdentifier( generatedName ).render( getDialect() );
cteNameMapping.put( key, cteName );
return cteName;
}
}
private String generateCteName(String baseName) {
String name = baseName;
int maxTries = 5;
for ( int i = 0; i < maxTries; i++ ) {
if ( !cteNameMapping.containsKey( name ) ) {
return name;
}
name = baseName + "_" + i;
}
throw new InterpretationException(
String.format(
"Couldn't generate CTE name for base name [%s] after %d tries",
baseName,
maxTries
)
);
}
private Literal getLiteral(SqmLiteral<?> value) {
return value == null ? null : (Literal) visitLiteral( value );
}
protected List<SearchClauseSpecification> visitSearchBySpecifications(
CteTable cteTable,
List<JpaSearchOrder> searchBySpecifications) {
if ( searchBySpecifications == null || searchBySpecifications.isEmpty() ) {
return null;
}View on GitHub (pinned to fad1729dce)
Solutions
- Give every CTE in the statement a unique explicit label instead of relying on generated names
- Reduce the number of CTEs: merge equivalent CTEs or inline the ones used only once
- Split the statement into multiple sequential queries so each statement registers fewer CTEs
- If labels are already unique and it still fails, file a Hibernate JIRA with the query - a genuinely unique base name should never exhaust 5 tries
Example fix
// before (criteria, same label reused across many branches)
cteContainer.with("data", dataQuery);
...
// after: unique labels per CTE
cteContainer.with("data_" + branchIndex, dataQuery); Defensive patterns
Strategy: try-catch
Validate before calling
// Before executing, sanity-check that CTE labels in one statement are unique
// (HQL): count labels in the with-clause
java.util.List<String> labels = java.util.Arrays.stream(hql.split("\\s+"))
.filter(w -> w.equalsIgnoreCase("with") || w.contains(",")) .count() > 5
? java.util.Collections.singletonList("review-cte-count")
: java.util.Collections.emptyList(); Try / catch
try {
Query<?> q = session.createQuery(hql);
return q.getResultList();
} catch (org.hibernate.query.sqm.InterpretationException e) {
log.error("Query failed to translate: {}", hql, e);
throw new QueryTranslationFailure(hql, e); // keep the HQL with the error for diagnosis
} Prevention
- Always pass explicit, unique labels when adding CTEs programmatically
- Keep with-clauses small: inline single-use CTEs instead of declaring them
- Log the generated HQL/SQM for dynamically built queries so collisions are diagnosable
When it happens
Trigger: A single HQL statement that registers six or more CTEs whose labels collapse to the same generated base name: many subqueries or union branches re-declaring the same CTE label, a criteria query with JpaCteCriteria added repeatedly under one name, or programmatically generated with-clauses where SqmCteTables carry no explicit name and their fallback names collide after identifier rendering.
Common situations: Programmatically built queries (criteria + CTE containers) in reporting/data-pipeline code; heavy use of union all with shared CTE labels; upgrades between Hibernate versions where CTE name generation changed; test suites generating very wide with-clauses.
Related errors
- Could not find CTE for name '" + cteName + "'!
- Select item at position ${i+1} in select list has no alias (
- Insert conflict 'do update' clause with constraint name is n
- Summarization is not supported by DBMS
- Insert conflict 'do update' clause with constraint name is n
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/399c72af818cb418.
Report an issue: GitHub.