{"record":{"id":"42a56c6800f71adc","repo":"hibernate/hibernate-orm","slug":"singlestore-json-exists-only-support-literal-json","errorCode":null,"errorMessage":"SingleStore json_exists only support literal json paths, but got {}","messagePattern":"SingleStore json_exists only support literal json paths, but got (.+?)","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonExistsFunction.java","lineNumber":41,"sourceCode":"\tpublic SingleStoreJsonExistsFunction(TypeConfiguration typeConfiguration) {\n\t\tsuper( typeConfiguration, true, false );\n\t}\n\n\t@Override\n\tprotected void render(\n\t\t\tSqlAppender sqlAppender,\n\t\t\tJsonExistsArguments arguments,\n\t\t\tReturnableType<?> returnType,\n\t\t\tSqlAstTranslator<?> walker) {\n\t\tif ( arguments.errorBehavior() != null && arguments.errorBehavior() != JsonExistsErrorBehavior.ERROR ) {\n\t\t\tthrow new QueryException( \"Can't emulate on error clause on SingleStore\" );\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_exists 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_match_any_exists(\" );\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 jsonParameterIndexAccess) {\n\t\t\t\tfinal String parameterName = jsonParameterIndexAccess.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":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonExistsFunction.java#L23-L59","documentation":"SingleStore's json_match_any_exists requires the JSON path to be decomposed into literal path constants, so the path argument must be a string literal. render() calls getLiteralValue on the path expression; a bind parameter or computed expression fails, and the resulting QueryException echoes the offending path expression.","triggerScenarios":"HQL `json_exists(e.doc, :path)` or a computed path like `json_exists(e.doc, concat('items[', i, ']'))` on SingleStoreDialect.","commonSituations":"Generic DAO layers that bind paths as parameters to plan-cache queries; multi-dialect code where PostgreSQL accepts parameterized paths via passing.","solutions":["Inline the path as a string literal: json_exists(e.doc, 'items[0]')","Concatenate a validated, whitelisted path into the HQL string in Java (mind injection)","Switch to a native query if the path must stay dynamic","Model frequently queried attributes as real columns instead of ad-hoc JSON paths"],"exampleFix":"// before\nem.createQuery(\"select e from E e where json_exists(e.doc, :path)\")\n    .setParameter(\"path\", \"items[0]\");\n\n// after: literal path in the query string\nem.createQuery(\"select e from E e where json_exists(e.doc, 'items[0]')\");","handlingStrategy":"validation","validationCode":"// The path must be a string literal; never bind it as a parameter on SingleStore\nstatic String literalJsonPath(String path, int index) {\n    // build from validated components only — no user input concatenation\n    if (!path.matches(\"[A-Za-z0-9_.\\\\[\\\\]-]*\")) throw new IllegalArgumentException(\"bad path\");\n    return path;\n}","typeGuard":null,"tryCatchPattern":"try {\n    return em.createQuery(\"select e from E e where json_exists(e.doc, :path)\")\n             .setParameter(\"path\", p).getResultList();\n} catch (QueryException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"literal json paths\")) {\n        // inline the path literal (validated) into the HQL and retry\n    }\n    throw e;\n}","preventionTips":["On SingleStore, inline JSON paths as literals instead of binding parameters","Whitelist-validate any path built dynamically before embedding it in HQL","Consider extracting hot JSON attributes into columns to avoid dynamic paths"],"tags":["hibernate","singlestore","json-exists","json-path","literal-required"],"backgroundTag":"json-path-must-be-literal","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}