hibernate/hibernate-orm · error · QueryException
Can't emulate json_objectagg 'with unique keys' clause.
Error message
Can't emulate json_objectagg 'with unique keys' clause.
What it means
SAP HANA lacks native json_objectagg, so Hibernate emulates it with string_agg. The emulation cannot enforce key uniqueness, so a WITH UNIQUE KEYS request is rejected with this QueryException before SQL is generated.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/json/HANAJsonObjectAggFunction.java:37
/**
* SAP HANA json_objectagg function.
*/
public class HANAJsonObjectAggFunction extends JsonObjectAggFunction {
public HANAJsonObjectAggFunction(TypeConfiguration typeConfiguration) {
super( ",", false, typeConfiguration );
}
@Override
protected void render(
SqlAppender sqlAppender,
JsonObjectAggArguments arguments,
Predicate filter,
ReturnableType<?> returnType,
SqlAstTranslator<?> translator) {
final boolean caseWrapper = filter != null;
if ( arguments.uniqueKeysBehavior() == JsonObjectAggUniqueKeysBehavior.WITH ) {
throw new QueryException( "Can't emulate json_objectagg 'with unique keys' clause." );
}
sqlAppender.appendSql( "'{'||string_agg(" );
renderArgument( sqlAppender, arguments.key(), JsonNullBehavior.NULL, translator );
sqlAppender.appendSql( "||':'||" );
if ( caseWrapper ) {
if ( arguments.nullBehavior() != JsonNullBehavior.ABSENT ) {
throw new QueryException( "Can't emulate json_objectagg filter clause when using 'null on null' clause." );
}
translator.getCurrentClauseStack().push( Clause.WHERE );
sqlAppender.appendSql( "case when " );
filter.accept( translator );
translator.getCurrentClauseStack().pop();
sqlAppender.appendSql( " then " );
renderArgument( sqlAppender, arguments.value(), arguments.nullBehavior(), translator );
sqlAppender.appendSql( " else null end)" );
}
else {
renderArgument( sqlAppender, arguments.value(), arguments.nullBehavior(), translator );View on GitHub (pinned to fad1729dce)
Solutions
- Remove WITH UNIQUE KEYS from the json_objectagg call on HANA.
- Deduplicate key/value pairs in a subquery or in Java before the aggregate.
- Use a native HANA query when unique-key enforcement must stay in the database.
- Validate keys for uniqueness in application code after the aggregate returns.
Example fix
// before select json_objectagg(k value v with unique keys) from Entity e // after select json_objectagg(k value v) from Entity e
Defensive patterns
Strategy: try-catch
Validate before calling
boolean hana = session.getJdbcServices().getDialect() instanceof org.hibernate.dialect.HANADialect;
if (hana && withUniqueKeys) {
throw new UnsupportedOperationException("HANA json_objectagg cannot enforce WITH UNIQUE KEYS; deduplicate first");
} Try / catch
try {
return session.createQuery(hql).getSingleResult();
} catch (org.hibernate.QueryException e) {
if (e.getMessage() != null && e.getMessage().contains("with unique keys")) {
// Retry without WITH UNIQUE KEYS after deduplicating in a subquery.
return session.createQuery(fallbackHql).getSingleResult();
}
throw e;
} Prevention
- Do not rely on WITH UNIQUE KEYS for correctness; deduplicate keys in a subquery or in Java.
- Check the HANA emulation notes before using optional json_objectagg clauses.
When it happens
Trigger: An HQL query on HANA calls json_objectagg(key VALUE value WITH UNIQUE KEYS). The check arguments.uniqueKeysBehavior() == JsonObjectAggUniqueKeysBehavior.WITH fires and rendering stops.
Common situations: Queries ported from Oracle or MySQL 8, where WITH UNIQUE KEYS is supported. Mappings that produce duplicate keys per group and rely on the database to drop duplicates.
Related errors
- Can't emulate json_objectagg filter clause when using 'null
- Can't emulate json_objectagg 'with unique keys' clause.
- Can't emulate json_arrayagg filter clause when using 'null o
- Can't emulate json_objectagg filter clause when using 'null
- Can't emulate json_objectagg 'with unique keys' clause.
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f2889baa4b865ac0.
Report an issue: GitHub.