hibernate/hibernate-orm · error · UnsupportedOperationException

Unsupported literal: ${literal}

Error message

Unsupported literal: ${literal}

What it means

The literal visitor only translates a fixed set of terminal token types (INTEGER_LITERAL, FLOAT_LITERAL, DOUBLE_LITERAL in this switch, after earlier branches handled other literal categories, parameters and nested expressions). Reaching the default arm means the parser produced a literal token the semantic builder does not handle - an unsupported literal syntax or a grammar/visitor mismatch, i.e. an internal limitation rather than a user mapping problem.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java:1992

	public SqmExpression<?> visitParameterOrNumberLiteral(HqlParser.ParameterOrNumberLiteralContext ctx) {
		if ( ctx.INTEGER_LITERAL() != null ) {
			return integerLiteral( ctx.INTEGER_LITERAL().getText() );
		}
		else if ( ctx.FLOAT_LITERAL() != null ) {
			return floatLiteral( ctx.FLOAT_LITERAL().getText() );
		}
		else if ( ctx.DOUBLE_LITERAL() != null ) {
			return doubleLiteral( ctx.DOUBLE_LITERAL().getText() );
		}
		else if ( ctx.parameter() != null ) {
			return (SqmExpression<?>) ctx.parameter().accept( this );
		}
		else if ( ctx.getChild( 0 ) instanceof TerminalNode firstChild ) {
			return switch ( firstChild.getSymbol().getType() ) {
				case HqlParser.INTEGER_LITERAL -> integerLiteral( ctx.getChild( 0 ).getText() );
				case HqlParser.FLOAT_LITERAL -> floatLiteral( ctx.getChild( 0 ).getText() );
				case HqlParser.DOUBLE_LITERAL -> doubleLiteral( ctx.getChild( 0 ).getText() );
				default -> throw new UnsupportedOperationException( "Unsupported literal: " + ctx.getChild( 0 ).getText() );
			};
		}
		else {
			return (SqmExpression<?>) ctx.getChild( 0 ).accept( this );
		}
	}

	public String getEntityName(HqlParser.EntityNameContext parserEntityName) {
		final var entityName = new StringBuilder();
		final var identifierList = parserEntityName.identifier();
		final int size = identifierList.size();
		for ( int i = 0; i < size; i++ ) {
			final var id = identifierList.get( i );
			if ( i > 0) {
				entityName.append( '.' );
			}
			entityName.append( visitIdentifier( id ) );
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rewrite the literal in a plain supported form (decimal number, quoted string, date/time literal)
  2. Bind the value as a query parameter instead of inlining it
  3. Upgrade hibernate-core to the latest patch release in case the literal form is now supported
  4. If it still reproduces, report it to Hibernate (HHH JIRA) with the exact literal text

Example fix

// before
select p from Payment p where p.amount > 0x1F

// after
select p from Payment p where p.amount > :minAmount  // bind 31 as parameter
Defensive patterns

Strategy: validation

Validate before calling

// Lint HQL for literal forms Hibernate does not translate (hex, octal)
static boolean hasUnsupportedLiteral(String hql) {
    return java.util.regex.Pattern.compile("\\b0[xX][0-9a-fA-F]+").matcher(hql).find();
}

Try / catch

try {
    return em.createQuery(hql, Payment.class).getResultList();
} catch (UnsupportedOperationException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unsupported literal")) {
        throw new IllegalArgumentException("Rewrite the literal as a parameter or decimal: " + hql, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Inline literals with unusual token forms (e.g. hexadecimal/octal-style numeric literals) that parse into an unhandled terminal node; version mixes where the grammar emits token types this visitor build does not translate.

Common situations: Copying native SQL literals into HQL; running hibernate-core versions with a parser/visitor gap; genuine Hibernate bugs after a grammar change (check the HHH JIRA before debugging your own mapping).

Related errors


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