hibernate/hibernate-orm · error · SemanticException
Can't use expression '" + expression + " without explicit na
Error message
Can't use expression '" + expression + " without explicit name in xmlforest function, because XML element names can only be derived from path expressions.
What it means
The xmlforest(criteria) function builds XML fragments where every element needs a name. A name can only be derived automatically from a path over a persistent attribute (SqmPath whose model is a PersistentAttribute); any other expression (literal, aggregate, arithmetic, subquery, parameter) must carry an explicit name by being an SqmNamedExpression. Otherwise Hibernate throws SemanticException because it cannot invent a valid XML element name.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java:6578
public <T> SqmExpression<T> named(Expression<T> expression, String name) {
return new SqmNamedExpression<>( (SqmExpression<T>) expression, name );
}
@Override
public SqmExpression<String> xmlforest(Expression<?>... elements) {
return xmlforest( asList( elements ) );
}
@Override
public SqmExpression<String> xmlforest(List<? extends Expression<?>> elements) {
final ArrayList<SqmExpression<?>> arguments = new ArrayList<>( elements.size() );
for ( Expression<?> expression : elements ) {
if ( expression instanceof SqmNamedExpression<?> ) {
arguments.add( (SqmNamedExpression<?>) expression );
}
else {
if ( !( expression instanceof SqmPath<?> path ) || !( path.getModel() instanceof PersistentAttribute<?, ?> attribute ) ) {
throw new SemanticException(
"Can't use expression '" + expression + " without explicit name in xmlforest function"+
", because XML element names can only be derived from path expressions."
);
}
arguments.add( new SqmNamedExpression<>( (SqmExpression<?>) expression, attribute.getName() ) );
}
}
return getFunctionDescriptor( "xmlforest" ).generateSqmExpression(
arguments,
null,
queryEngine
);
}
@Override
public SqmExpression<String> xmlconcat(Expression<?>... elements) {
return xmlconcat( asList( elements ) );
}View on GitHub (pinned to fad1729dce)
Solutions
- Attach an explicit name to computed elements using the alias support so they become named expressions: cb.xmlforest(root.get("name"), cb.count(...).alias("order_count")) or your builder's named wrapper (SqmNamedExpression via alias()).
- Restrict automatically named elements to direct attribute paths (root.get("attr")).
- If alias() alone doesn't register as a named expression in your version, project through cb.concat/xmlforest with explicit xmlserialize/xmlconcat names or use HQL 'xmlforest(name as x, ...)' with aliases.
Example fix
// before
Expression<Long> cnt = cb.count(orderRoot.get("id"));
cb.xmlforest(customer.get("name"), cnt); // cnt is not a path -> SemanticException
// after
Expression<Long> cnt = cb.count(orderRoot.get("id")).alias("orderCount"); // explicit name
cb.xmlforest(customer.get("name"), cnt); Defensive patterns
Strategy: validation
Validate before calling
boolean canAutoName(Expression<?> e) {
return e instanceof Path<?> p && p.getModel() instanceof Attribute<?, ?>;
}
// every non-path element must be named:
if (!canAutoName(e) && e.getAlias() == null) throw new IllegalArgumentException("element needs explicit alias/name"); Type guard
static boolean xmlforestSafe(Expression<?> e) {
return (e instanceof Path<?> p && p.getModel() instanceof Attribute<?, ?>)
|| e.getAlias() != null; // aliased expressions carry a name
} Try / catch
try {
x = cb.xmlforest(elements);
} catch (SemanticException e) {
if (e.getMessage().contains("xmlforest")) { /* alias each computed element and rebuild */ }
else throw e;
} Prevention
- Alias every computed element (count, sum, coalesce, literal) before passing it to xmlforest.
- Reserve unaliased elements for direct attribute paths.
- Add a builder-level check that all xmlforest arguments are paths or aliased.
When it happens
Trigger: cb.xmlforest(root.get("name"), cb.count(rootJoin.get("id"))) — the count() has no attribute name; passing literals (cb.literal(42)), coalesce/case expressions, or alias-less function results; calling xmlforest(Expression...) with values produced by helper builders that never call alias().
Common situations: Porting SQL 'xmlforest(...)' projections that mix columns and computed values; report builders generating XML output where aggregates like sum()/count() are added without labels; XML export features on PostgreSQL.
Related errors
- Parameter %d of function 'xmlforest()' is not named
- Invalid XML element name passed to 'xmlforest()': %s
- Operand of 'member of' operator must be a plural path
- Informix does not support binary literals
- Could not instantiate named strategy class [%s]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/062d9d147fc948de.
Report an issue: GitHub.