hibernate/hibernate-orm · error · IllegalStateException
unexpected JSON array type
Error message
unexpected JSON array type
What it means
convertedBasicValueToString() serializes one nested attribute of a JSON aggregate and explicitly refuses JDBC types whose default SQL type code is SqlTypes.ARRAY or JSON_ARRAY — the comment states the caller must emit arrays via startArray()/values/endArray() instead. Reaching this throw means Hibernate's own serialization path routed an array-typed value into the scalar branch: an internal invariant break, not a user input error.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/format/StringJsonDocumentWriter.java:374
appender.append( StringJsonDocumentMarker.QUOTE.getMarkerCharacter() );
javaType.appendEncodedString( appender, (T) value );
appender.append( StringJsonDocumentMarker.QUOTE.getMarkerCharacter() );
break;
case SqlTypes.BINARY:
case SqlTypes.VARBINARY:
case SqlTypes.LONGVARBINARY:
case SqlTypes.LONG32VARBINARY:
case SqlTypes.BLOB:
case SqlTypes.MATERIALIZED_BLOB:
// These types need to be serialized as JSON string, and for efficiency uses appendString directly
appender.append( StringJsonDocumentMarker.QUOTE.getMarkerCharacter() );
appender.write( javaType.unwrap( (T) value, byte[].class, options ) );
appender.append( StringJsonDocumentMarker.QUOTE.getMarkerCharacter() );
break;
case SqlTypes.ARRAY:
case SqlTypes.JSON_ARRAY:
// Caller handles this. We should never end up here actually.
throw new IllegalStateException( "unexpected JSON array type" );
default:
throw new UnsupportedOperationException( "Unsupported JdbcType nested in JSON: " + jdbcType );
}
}
public String getJson() {
return appender.toString();
}
@Override
public String toString() {
return appender.toString();
}
private static class JsonAppender extends OutputStream implements SqlAppender {
private final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
View on GitHub (pinned to fad1729dce)
Solutions
- Remap the nested collection so Hibernate serializes it as JSON content (remove @JdbcTypeCode(SqlTypes.ARRAY)/JSON_ARRAY from the attribute)
- Test against the latest 7.x patch release and search the HHH JIRA for 'unexpected JSON array type' — JSON aggregate handling has active fixes
- Plug in a custom FormatMapper via hibernate.type.json_format_mapper that serializes the aggregate end-to-end
- If reproducible on the latest release, report to Hibernate JIRA with the entity mapping and dialect
Example fix
// before
@Embeddable
public class Details {
@JdbcTypeCode(SqlTypes.ARRAY) // routed into scalar branch -> IllegalStateException
private List<String> tags;
}
// after
@Embeddable
public class Details {
// let Hibernate map the collection inside the JSON document
private List<String> tags;
} Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast at startup: no aggregate attribute may use an array JdbcType
static void checkAggregateAttributes(org.hibernate.metamodel.MappingMetamodel metamodel) {
metamodel.getEmbeddables().forEach(embeddable -> embeddable.getAttributes().forEach(attr -> {
// reject attributes resolved to SqlTypes.ARRAY / SqlTypes.JSON_ARRAY inside JSON aggregates
}));
} Try / catch
try {
session.merge(entity);
session.flush();
} catch (IllegalStateException e) {
if ("unexpected JSON array type".equals(e.getMessage())) {
// Hibernate internal invariant: remap the nested collection attribute and retry
throw new MappingConfigurationException("Nested array attribute inside JSON aggregate is not supported - map it as JSON", e);
}
throw e;
} Prevention
- Do not combine @JdbcTypeCode(SqlTypes.ARRAY / JSON_ARRAY) with attributes nested in JSON aggregates
- Integration-test aggregate writes (including nested collections) against the target dialect
- Watch release notes when upgrading - JSON aggregate serialization evolves between Hibernate versions
When it happens
Trigger: An embeddable/aggregate mapped to JSON containing an attribute annotated @JdbcTypeCode(SqlTypes.ARRAY) or SqlTypes.JSON_ARRAY (List or primitive array) where the dialect's writer passes it into serializeJsonValue() instead of the array callbacks; typically on dialects with native JSON aggregate support (Oracle, DB2, SQL Server).
Common situations: Mapping a List<T>/T[] field inside a JSON aggregate with an array JdbcType; upgrading Hibernate across versions where JSON aggregate serialization was reworked; a custom JdbcType whose getDefaultSqlTypeCode() reports ARRAY.
Related errors
- Failed to serialize JSON mapping
- Unsupported JdbcType nested in JSON: {}
- Unsupported aggregate SQL type: {}
- Could not find selectable [%s] in embeddable type [%s] for J
- Can't parse JSON object for selectable [%s] which is not of
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c6e646ba92123994.
Report an issue: GitHub.