hibernate/hibernate-orm · error · QueryException

Can't emulate on error clause on SingleStore

Error message

Can't emulate on error clause on SingleStore

What it means

Standard SQL json_exists can specify an error behavior (TRUE/FALSE/UNKNOWN/ERROR ON ERROR). SingleStore's json_match_any_exists emulation has no way to suppress or convert path errors, so render() accepts only the default ERROR ON ERROR (or no clause at all) and throws QueryException for any other behavior.

Source

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

import org.hibernate.type.spi.TypeConfiguration;

/**
 * SingleStore json_exists function.
 */
public class SingleStoreJsonExistsFunction extends JsonExistsFunction {

	public SingleStoreJsonExistsFunction(TypeConfiguration typeConfiguration) {
		super( typeConfiguration, true, false );
	}

	@Override
	protected void render(
			SqlAppender sqlAppender,
			JsonExistsArguments arguments,
			ReturnableType<?> returnType,
			SqlAstTranslator<?> walker) {
		if ( arguments.errorBehavior() != null && arguments.errorBehavior() != JsonExistsErrorBehavior.ERROR ) {
			throw new QueryException( "Can't emulate on error clause on SingleStore" );
		}
		final String jsonPath;
		try {
			jsonPath = walker.getLiteralValue( arguments.jsonPath() );
		}
		catch (Exception ex) {
			throw new QueryException( "SingleStore json_exists only support literal json paths, but got " + arguments.jsonPath() );
		}
		final List<JsonPathHelper.JsonPathElement> jsonPathElements = JsonPathHelper.parseJsonPathElements( jsonPath );
		sqlAppender.appendSql( "json_match_any_exists(" );
		arguments.jsonDocument().accept( walker );
		for ( JsonPathHelper.JsonPathElement pathElement : jsonPathElements ) {
			sqlAppender.appendSql( ',' );
			if ( pathElement instanceof JsonPathHelper.JsonAttribute attribute ) {
				sqlAppender.appendSingleQuoteEscapedString( attribute.attribute() );
			}
			else if ( pathElement instanceof JsonPathHelper.JsonParameterIndexAccess jsonParameterIndexAccess) {
				final String parameterName = jsonParameterIndexAccess.parameterName();

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove the 'on error' clause and accept the default ERROR behavior
  2. Pre-filter invalid JSON documents (native is_json-style check) before running json_exists
  3. Catch the resulting database error in Java and treat it as a false/unknown result
  4. Run the existence check as a native query that handles errors explicitly

Example fix

// before
select e from E e where json_exists(e.doc, 'a.b' false on error)

// after
select e from E e where json_exists(e.doc, 'a.b')
Defensive patterns

Strategy: validation

Validate before calling

// Only the default ERROR ON ERROR is emulatable on SingleStore
static boolean jsonExistsOnErrorOk(String onErrorClause, Dialect d) {
    return !(d instanceof SingleStoreDialect)
        || onErrorClause == null || onErrorClause.isBlank();
}

Try / catch

try {
    return em.createQuery(hql).getResultList(); // '... false on error'
} catch (QueryException e) {
    if (e.getMessage() != null && e.getMessage().contains("on error clause")) {
        // strip the on-error clause; catch the JDBC error in Java as the fallback behavior
    }
    throw e;
}

Prevention

When it happens

Trigger: HQL `json_exists(e.doc, 'a.b' false on error)` (also `true on error` / `unknown on error`) on SingleStoreDialect; omitting the clause works.

Common situations: Queries ported from Oracle/PostgreSQL where 'false on error' guards malformed documents; defensive JSON probing written against more permissive backends.

Related errors


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