hibernate/hibernate-orm · error · QueryException

SingleStore json_array_insert function last path parameter m

Error message

SingleStore json_array_insert function last path parameter must be an array index element

What it means

The SingleStore json_array_insert emulation derives the splice position from the LAST path element, which must be an array index access like [1]. If the final element is an attribute or the path is otherwise not index-terminated, getArrayIndex cannot determine where to insert and throws QueryException.

Source

Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonArrayInsertFunction.java:80

		json.accept( translator );
		buildJsonPath( sqlAppender, jsonPath, jsonPathElements );
		sqlAppender.appendSql( "))," );
		sqlAppender.appendSql( arrayIndex );
		sqlAppender.appendSql( ", 0, " );
		value.accept( translator );
		sqlAppender.appendSql( ") END" );
		if ( jsonPathElements.size() > 1 ) {
			sqlAppender.appendSql( ')' );
		}
	}

	private static int getArrayIndex(List<JsonPathHelper.JsonPathElement> jsonPathElements) {
		if ( jsonPathElements.isEmpty() ) {
			throw new QueryException( "SingleStore json_array_insert function requires at least one json path element" );
		}
		JsonPathHelper.JsonPathElement lastPathElement = jsonPathElements.get( jsonPathElements.size() - 1 );
		if ( !( lastPathElement instanceof JsonPathHelper.JsonIndexAccess ) ) {
			throw new QueryException(
					"SingleStore json_array_insert function last path parameter must be an array index element" );
		}
		return ( (JsonPathHelper.JsonIndexAccess) lastPathElement ).index();
	}

	private static boolean isNumeric(SqlAstNode value) {
		return value instanceof UnparsedNumericLiteral<?>;
	}

	private static void buildJsonArrayInsertValue(SqlAppender sqlAppender, SqlAstNode value) {
		sqlAppender.appendSql( "json_splice_" );
		sqlAppender.appendSql( isNumeric( value ) ? "double(" : "string(" );
	}

	private static void buildJsonPath(
			SqlAppender sqlAppender, Expression jsonPath, List<JsonPathHelper.JsonPathElement> jsonPathElements) {
		for ( int i = 0; i < jsonPathElements.size() - 1; i++ ) {
			JsonPathHelper.JsonPathElement pathElement = jsonPathElements.get( i );

View on GitHub (pinned to fad1729dce)

Solutions

  1. End the path with the target array index: 'items[0]'
  2. Use json_set/json_insert (or json_object building) when the target is an object attribute
  3. Assert in code that generated paths end with [<int>] before running the query

Example fix

// before (last segment is an attribute)
update E e set e.doc = json_array_insert(e.doc, 'items[0].label', :v)

// after (last segment is an array index)
update E e set e.doc = json_array_insert(e.doc, 'items[0]', :v)
Defensive patterns

Strategy: validation

Validate before calling

// Last path segment must be an array index [n]
private static final Pattern ENDS_WITH_INDEX = Pattern.compile("\\[\\d+\\]\\s*$");
static boolean validInsertPath(String path) {
    return path != null && !"$".equals(path.trim()) && ENDS_WITH_INDEX.matcher(path).find();
}

Try / catch

try {
    em.createQuery(hql).executeUpdate();
} catch (QueryException e) {
    if (e.getMessage() != null && e.getMessage().contains("array index element")) {
        // fix the path to end with [n] or switch to json_set for object targets
    }
    throw e;
}

Prevention

When it happens

Trigger: HQL `json_array_insert(e.doc, 'items[0].label', :v)` — any path whose last segment is not [n] — on SingleStoreDialect.

Common situations: Paths written object-insert style (json_set/json_insert semantics) reused with json_array_insert; path-building code that drops the trailing index by an off-by-one.

Related errors


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