hibernate/hibernate-orm · error · IllegalArgumentException

Can't render parameter as literal, no literal formatter foun

Error message

Can't render parameter as literal, no literal formatter found

What it means

In certain SQL positions Hibernate must render a JDBC parameter inline as a literal (e.g. limit/offset values on dialects that cannot bind parameters there, or inlined static parameters). renderAsLiteral asks the parameter's JdbcMapping for a JdbcLiteralFormatter; if the mapping provides none (common for exotic/basic-java-type mappings), rendering is impossible and this IllegalArgumentException is thrown.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java:7656

		if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.NO_UNTYPED ) {
			renderCasted( literal );
		}
		else {
			appendSql( SqlAppender.NULL_KEYWORD );
		}
	}

	protected void renderAsLiteral(JdbcParameter jdbcParameter, Object literalValue) {
		if ( literalValue == null ) {
			renderNull( new QueryLiteral<>( null, (BasicValuedMapping) jdbcParameter.getExpressionType() ) );
		}
		else {
			assert jdbcParameter.getExpressionType().getJdbcTypeCount() == 1;
			final JdbcMapping jdbcMapping = jdbcParameter.getExpressionType().getSingleJdbcMapping();
			//noinspection unchecked
			final JdbcLiteralFormatter<Object> literalFormatter = jdbcMapping.getJdbcLiteralFormatter();
			if ( literalFormatter == null ) {
				throw new IllegalArgumentException( "Can't render parameter as literal, no literal formatter found" );
			}
			else {
				literalFormatter.appendJdbcLiteral( this, literalValue, dialect, getWrapperOptions() );
			}
		}
	}

	@Override
	public void visitUnaryOperationExpression(UnaryOperation unaryOperationExpression) {
		if ( unaryOperationExpression.getOperator() == UnaryArithmeticOperator.UNARY_PLUS ) {
			appendSql( UnaryArithmeticOperator.UNARY_PLUS.getOperatorChar() );
		}
		else {
			appendSql( UnaryArithmeticOperator.UNARY_MINUS.getOperatorChar() );
		}

		unaryOperationExpression.getOperand().accept( this );
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use a standard Java/JDBC type for the parameter (Integer, String, LocalDate...) that has a built-in formatter
  2. For custom types, register a BasicType/JavaType that supplies a JdbcLiteralFormatter
  3. Avoid the construct that forces literal rendering (e.g. use setMaxResults so the dialect takes the native parameter path)
  4. Upgrade Hibernate - formatter coverage for more JDBC types improves by version

Example fix

// before
custom BasicType without literal formatter used where dialect inlines parameters

// after
// register the type with a formatter
BasicType<MyType> t = new MyTypeRenderer(new MyTypeJavaType() {
    @Override public JdbcLiteralFormatter<MyType> getJdbcLiteralFormatter() { return (appender, value, dialect, wrapper) -> appender.appendSql(value.render()); }
});
Defensive patterns

Strategy: fallback

Validate before calling

// Before executing with inlined parameters, confirm the mapping can render literals
JdbcMapping m = (JdbcMapping) param.getExpressionType().getSingleJdbcMapping();
if (m.getJdbcLiteralFormatter() == null) {
    // switch the parameter to a standard type or avoid the literal-rendering construct
}

Try / catch

try {
    query.list();
} catch (IllegalArgumentException e) {
    if ("Can't render parameter as literal, no literal formatter found".equals(e.getMessage())) {
        // rebind the parameter with a standard Java type and retry
    } else throw e;
}

Prevention

When it happens

Trigger: A query whose parameter must be rendered literally (dialect-specific limit emulation, in-clause parameter inlining, or explicit literal rendering mode) where the bound parameter's type has getJdbcLiteralFormatter() == null - e.g. custom BasicType/JavaType without a literal formatter, or certain binary/java-object mappings.

Common situations: Custom UserTypes/BasicTypes that implement the binder but not the literal formatter; pagination on dialects that inline the fetch value; switching a parameter's Java type to one lacking formatter support; Hibernate 6 migration where literal rendering paths expanded.

Related errors


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