{"record":{"id":"25828e487049b34d","repo":"hibernate/hibernate-orm","slug":"singlestore-json-value-only-support-literal-json-p","errorCode":null,"errorMessage":"SingleStore json_value only support literal json paths, but got \" + arguments.jsonPath() + \"","messagePattern":"SingleStore json_value only support literal json paths, but got \" \\+ arguments\\.jsonPath\\(\\) \\+ \"","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonValueFunction.java","lineNumber":54,"sourceCode":"\t\t\tthrow new QueryException( \"Can't emulate on error clause on SingleStore\" );\n\t\t}\n\t\tif ( arguments.emptyBehavior() != null && arguments.emptyBehavior() != JsonValueEmptyBehavior.NULL ) {\n\t\t\tthrow new QueryException( \"Can't emulate on empty clause on SingleStore\" );\n\t\t}\n\t\tif ( arguments.returningType() != null ) {\n\t\t\tif ( arguments.returningType().getJdbcMapping().getJdbcType().isBoolean() ) {\n\t\t\t\tsqlAppender.append( \"case \" );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsqlAppender.append( \"cast(\" );\n\t\t\t}\n\t\t}\n\t\tfinal String jsonPath;\n\t\ttry {\n\t\t\tjsonPath = walker.getLiteralValue( arguments.jsonPath() );\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new QueryException( \"SingleStore json_value only support literal json paths, but got \" + arguments.jsonPath() );\n\t\t}\n\t\tfinal List<JsonPathHelper.JsonPathElement> jsonPathElements = JsonPathHelper.parseJsonPathElements( jsonPath );\n\t\tsqlAppender.appendSql( \"json_extract_string(\" );\n\t\targuments.jsonDocument().accept( walker );\n\t\tfor ( JsonPathHelper.JsonPathElement pathElement : jsonPathElements ) {\n\t\t\tsqlAppender.appendSql( ',' );\n\t\t\tif ( pathElement instanceof JsonPathHelper.JsonAttribute attribute ) {\n\t\t\t\tsqlAppender.appendSingleQuoteEscapedString( attribute.attribute() );\n\t\t\t}\n\t\t\telse if ( pathElement instanceof JsonPathHelper.JsonParameterIndexAccess indexParameter) {\n\t\t\t\tfinal String parameterName = indexParameter.parameterName();\n\t\t\t\tthrow new QueryException( \"JSON path [\" + jsonPath + \"] uses parameter [\" + parameterName + \"] that is not passed\" );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsqlAppender.appendSql( '\\'' );\n\t\t\t\tsqlAppender.appendSql( ( (JsonPathHelper.JsonIndexAccess) pathElement ).index() );\n\t\t\t\tsqlAppender.appendSql( '\\'' );\n\t\t\t}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonValueFunction.java#L36-L72","documentation":"The SingleStore emulation of json_value must parse the JSON path at SQL-render time to expand it into json_extract_string(doc, 'attr', ...) arguments, so the path has to be a literal. When the second argument is a bind parameter, walker.getLiteralValue(arguments.jsonPath()) throws and the dialect rethrows this QueryException stating that only literal paths are supported.","triggerScenarios":"HQL like: select json_value(e.doc, :path) from Event e with query.setParameter(\"path\", '$.name'). Any parameter expression in the jsonpath argument position triggers it; a string literal '$.name' works fine.","commonSituations":"Dynamic field extraction where the field name is only known at runtime; generic JSON APIs migrated from Oracle/PostgreSQL dialects; reusing one query text with different paths.","solutions":["Inline the path as a string literal: json_value(e.doc, '$.name').","Build the HQL string with the literal path interpolated - validate the path against a strict pattern (e.g. ^\\$[.A-Za-z0-9_\\[\\]-]*$) to prevent injection.","Maintain a whitelist of pre-built queries per field and select among them.","Use a native query where the path can be a real bind parameter."],"exampleFix":"// before - throws: path is a bind parameter\nsession.createQuery(\"select json_value(e.doc, :p) from Event e\", String.class)\n        .setParameter(\"p\", \"$.name\")\n\n// after - literal path\nsession.createQuery(\"select json_value(e.doc, '$.name') from Event e\", String.class)","handlingStrategy":"fallback","validationCode":"boolean safe = path.matches(\"^\\$[.A-Za-z0-9_\\[\\]'-]*$\");\nif (!safe) throw new IllegalArgumentException(\"untrusted json path\");\nString hql = \"select json_value(e.doc, '\" + path + \"') from Event e\";","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(hql, String.class).getResultList();\n} catch (QueryException e) {\n    if (e.getMessage().contains(\"literal json paths\")) {\n        throw new IllegalArgumentException(\"json path must be a literal: \" + path, e);\n    }\n    throw e;\n}","preventionTips":["Inline the jsonpath as a literal on SingleStore - never bind it","Whitelist dynamic paths before interpolating them into HQL"],"tags":["singlestore","json","json-value","hql","bind-parameter","literal-required"],"backgroundTag":"unsupported-bind-parameter","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}