hibernate/hibernate-orm · error · QueryException

JSON path [{jsonPath}] uses parameter [{parameterName}] that

Error message

JSON path [{jsonPath}] uses parameter [{parameterName}] that is not passed

What it means

When a dialect inlines the passing clause into a single concatenated path literal, each $name reference must resolve to an expression in the passing clause. The helper splits the path, extracts the identifier, and looks it up in passingClause.getPassingExpressions(). A missing name throws this QueryException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/json/JsonPathHelper.java:115

		sqlAppender.append( '\'' );
		sqlAppender.append( prefix );
		final int start;
		if ( parts[0].isEmpty() ) {
			start = 2;
			sqlAppender.append( '$' );
			sqlAppender.append( parts[1] );
		}
		else {
			start = 0;
		}
		for ( int i = start; i < parts.length; i++ ) {
			final String part = parts[i];

			final int parameterNameEndIndex = indexOfNonIdentifier( part, 0 );
			final String parameterName = part.substring( 0, parameterNameEndIndex );
			final Expression expression = passingClause.getPassingExpressions().get( parameterName );
			if ( expression == null ) {
				throw new QueryException( "JSON path [" + jsonPath + "] uses parameter [" + parameterName + "] that is not passed" );
			}
			final Object literalValue = walker.getLiteralValue( expression );
			if ( literalValue instanceof String string ) {
				appendLiteral( sqlAppender, 0, string );
			}
			else {
				sqlAppender.appendSql( String.valueOf( literalValue ) );
			}
			appendLiteral( sqlAppender, parameterNameEndIndex, part );
		}
		sqlAppender.appendSql( '\'' );
	}

	private static void appendLiteral(SqlAppender sqlAppender, int parameterNameEndIndex, String part) {
		for ( int j = parameterNameEndIndex; j < part.length(); j++ ) {
			final char c = part.charAt( j );
			if ( c == '\'') {
				sqlAppender.appendSql( '\'' );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add the missing binding with an exact alias match: PASSING :i AS name.
  2. Verify the identifier characters: the parser reads the name only up to the first non-identifier character.
  3. Replace the parameter reference with a literal index or literal attribute.
  4. Add a startup check that compares $names in the path with the passing aliases you bind.

Example fix

// before
select json_value(e.doc, '$.items[$idx]') from Entity e

// after
select json_value(e.doc, '$.items[$idx]' passing :i as idx) from Entity e
Defensive patterns

Strategy: validation

Validate before calling

static void checkPassingBindings(String path, Map<String, Object> bindings) {
    var m = java.util.regex.Pattern.compile("\\$(\\w+)").matcher(path);
    while (m.find()) {
        if (!bindings.containsKey(m.group(1))) {
            throw new IllegalArgumentException("JSON path references unbound parameter $" + m.group(1));
        }
    }
}

Try / catch

try {
    return session.createQuery(hql, String.class).getSingleResult();
} catch (org.hibernate.QueryException e) {
    if (e.getMessage() != null && e.getMessage().contains("that is not passed")) {
        throw new IllegalArgumentException("Add the missing PASSING binding: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A json_value or json_query query on an emulating dialect (for example H2) uses a path with [$name] or $name but the PASSING clause does not bind that exact name.

Common situations: Alias typos between the path and the AS alias. Paths assembled at runtime from templates that reference parameters the query never declared.

Related errors


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