hibernate/hibernate-orm · error · QueryException
H2 json_query only support literal json paths, but got " + j
Error message
H2 json_query only support literal json paths, but got " + jsonPathExpression
What it means
The H2 json_query() emulation rewrites the SQL/JSON path into H2 dereference operators, which requires the concrete path text at translation time. When the path argument is a bind parameter or other non-literal expression, walker.getLiteralValue() fails and Hibernate rethrows it as this QueryException during SQL rendering.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/json/H2JsonQueryFunction.java:67
walker
);
}
static void appendJsonQuery(
SqlAppender sqlAppender,
Expression jsonDocument,
boolean isJsonType,
Expression jsonPathExpression,
@Nullable JsonPathPassingClause passingClause,
@Nullable JsonQueryWrapMode wrapMode,
@Nullable JsonQueryEmptyBehavior emptyBehavior,
SqlAstTranslator<?> walker) {
final String jsonPath;
try {
jsonPath = walker.getLiteralValue( jsonPathExpression );
}
catch (Exception ex) {
throw new QueryException( "H2 json_query only support literal json paths, but got " + jsonPathExpression );
}
appendJsonQuery( sqlAppender, jsonDocument, isJsonType, jsonPath, passingClause, wrapMode, emptyBehavior, walker );
}
static void appendJsonQuery(
SqlAppender sqlAppender,
Expression jsonDocument,
boolean isJsonType,
String jsonPath,
@Nullable JsonPathPassingClause passingClause,
@Nullable JsonQueryWrapMode wrapMode,
@Nullable JsonQueryEmptyBehavior emptyBehavior,
SqlAstTranslator<?> walker) {
if ( emptyBehavior == JsonQueryEmptyBehavior.EMPTY_ARRAY || emptyBehavior == JsonQueryEmptyBehavior.EMPTY_OBJECT ) {
sqlAppender.appendSql( "coalesce(" );
}
if ( wrapMode == JsonQueryWrapMode.WITH_WRAPPER ) {View on GitHub (pinned to fad1729dce)
Solutions
- Inline the path as a literal: json_query(d.doc, '$.items[*]')
- Parameterize parts inside a literal path with PASSING: json_query(d.doc, '$.items[$i]' passing :idx as i)
- Fall back to a native H2 query for fully dynamic paths
- Keep a whitelist of pre-validated literal-path queries
Example fix
// before - throws on H2 select json_query(d.doc, :path) from Document d // after - literal path with passing for the variable index select json_query(d.doc, '$.items[$i]' passing :idx as i) from Document d
Defensive patterns
Strategy: validation
Validate before calling
// Heuristic lint: json_query paths must be string literals on H2
private static final Pattern PARAM_QUERY_PATH =
Pattern.compile("(?i)json_query\\s*\\([^,]+,\\s*:\\w+");
static void assertLiteralJsonPaths(String hql) {
if (PARAM_QUERY_PATH.matcher(hql).find()) {
throw new IllegalArgumentException(
"json_query path must be a string literal on H2; use PASSING for variable parts");
}
} Type guard
// Java predicate (type-guard analogue) for Criteria/SQM path expressions
static boolean isLiteralPath(org.hibernate.query.sqm.tree.expression.SqmExpression<?> pathExpr) {
return pathExpr instanceof org.hibernate.query.sqm.tree.expression.SqmLiteral<?>;
} Try / catch
try {
return session.createQuery(hql, String.class).getResultList();
} catch (org.hibernate.QueryException e) {
if (e.getMessage() != null && e.getMessage().contains("only support literal json paths")) {
throw new IllegalArgumentException("Inline the json_query path as a literal: " + hql, e);
}
throw e;
} Prevention
- Keep json_query paths as literals; move variability into the PASSING clause
- Do not accept raw user input as a JSON path on H2-based deployments
- Exercise every json_* query under each supported dialect in CI
When it happens
Trigger: HQL on H2 with a non-literal json_query path: select json_query(d.doc, :path) from Document d, or a path produced by concatenation/function calls.
Common situations: Dynamic reporting where the extraction path is stored per customer or per tenant; H2 test profiles failing while the PostgreSQL production profile (whose emulation accepts parameter paths) passes.
Related errors
- H2 json_value only support literal json paths, but got " + a
- H2 json_table() only supports literal json paths, but got "
- H2 json_table() only supports literal json paths, but got {j
- CockroachDB json_value only support literal json paths, but
- JSON path [" + JsonPathHelper.toJsonPath( jsonPathElements )
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/33354962b6831006.
Report an issue: GitHub.