hibernate/hibernate-orm · error · UnsupportedOperationException
Unsupported JdbcType nested in JSON: {}
Error message
Unsupported JdbcType nested in JSON: {} What it means
The same scalar branch whitelists the JDBC type codes it can render into JSON (integers, floats, booleans, char/varchar/clob strings, enums, dates/times, decimal, duration, uuid, binary). Any other JdbcType falls through to UnsupportedOperationException naming the type — Hibernate cannot serialize that nested attribute of the JSON aggregate at all.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/format/StringJsonDocumentWriter.java:376
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();
private final StringBuilder sb;
private boolean escape;View on GitHub (pinned to fad1729dce)
Solutions
- Read the message — it names the exact jdbcType; remap that attribute to a supported representation (e.g. AttributeConverter Point→WKT String, Duration→ISO-8601 String, nested JSON→String)
- Move the unsupported attribute out of the JSON aggregate into its own column
- Register a custom FormatMapper via hibernate.type.json_format_mapper that knows how to render the type
- Add an integration test that round-trips the aggregate so unsupported types fail at build time, not in production
Example fix
// before
@Embeddable
public class Address {
private org.locationtech.jts.geom.Point location; // SqlTypes.GEOMETRY -> UnsupportedOperationException
}
// after
@Embeddable
public class Address {
@Convert(converter = PointToStringConverter.class)
private Point location; // stored as WKT string inside the JSON
} Defensive patterns
Strategy: fallback
Validate before calling
static final Set<Integer> SUPPORTED = Set.of(
SqlTypes.TINYINT, SqlTypes.SMALLINT, SqlTypes.INTEGER, SqlTypes.BOOLEAN, SqlTypes.BIT,
SqlTypes.BIGINT, SqlTypes.FLOAT, SqlTypes.REAL, SqlTypes.DOUBLE, SqlTypes.CHAR, SqlTypes.NCHAR,
SqlTypes.VARCHAR, SqlTypes.NVARCHAR, SqlTypes.LONGVARCHAR, SqlTypes.LONGNVARCHAR,
SqlTypes.LONG32VARCHAR, SqlTypes.LONG32NVARCHAR, SqlTypes.CLOB, SqlTypes.MATERIALIZED_CLOB,
SqlTypes.NCLOB, SqlTypes.MATERIALIZED_NCLOB, SqlTypes.ENUM, SqlTypes.NAMED_ENUM,
SqlTypes.DATE, SqlTypes.TIME, SqlTypes.TIME_WITH_TIMEZONE, SqlTypes.TIME_UTC, SqlTypes.TIMESTAMP,
SqlTypes.TIMESTAMP_WITH_TIMEZONE, SqlTypes.TIMESTAMP_UTC, SqlTypes.DECIMAL, SqlTypes.NUMERIC,
SqlTypes.DURATION, SqlTypes.UUID, SqlTypes.BINARY, SqlTypes.VARBINARY, SqlTypes.LONGVARBINARY,
SqlTypes.LONG32VARBINARY, SqlTypes.BLOB, SqlTypes.MATERIALIZED_BLOB);
// verify each aggregate attribute's jdbcType.getDefaultSqlTypeCode() is in SUPPORTED before enabling the mapping Try / catch
try {
session.persist(entity);
session.flush();
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unsupported JdbcType nested in JSON")) {
// e.getMessage() names the jdbcType: convert that attribute or exclude it from the aggregate
throw new MappingConfigurationException(e.getMessage(), e);
}
throw e;
} Prevention
- Keep exotic types (geometry, interval, nested JSON) out of JSON aggregates or convert them to String via AttributeConverter
- Add a startup or test-time check listing the JDBC type codes of every aggregate attribute
- Provide a custom FormatMapper (hibernate.type.json_format_mapper) for types Hibernate cannot render natively
When it happens
Trigger: An embeddable mapped as a JSON aggregate (@JdbcTypeCode(SqlTypes.JSON) / @AggregateMapping) containing an attribute whose JDBC type is outside the switch: geometry (SqlTypes.GEOMETRY), nested JSON (SqlTypes.JSON), SQLXML, INTERVAL, or any custom user JdbcType.
Common situations: Adding a new attribute (Point, Interval, nested JSONB) to an @Embeddable persisted as JSON; dialect-specific types; upgrading Hibernate where the supported-type list changed between versions.
Related errors
- Failed to serialize JSON mapping
- unexpected JSON array type
- Could not find selectable [%s] in embeddable type [%s] for J
- Can't parse JSON object for selectable [%s] which is not of
- Expected JSON object end, but none found.
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3d874b8c716e562c.
Report an issue: GitHub.