hibernate/hibernate-orm · error · UnsupportedOperationException
Unsupported JdbcType nested in struct:
Error message
Unsupported JdbcType nested in struct:
What it means
XmlHelper.convertedBasicValueToString serializes a fixed set of JDBC type families: numerics, booleans, chars/text, enums, dates/times/timestamps, binary, UUID, duration, and arrays. Writing an XML/struct aggregate that contains a nested value of any other JDBC kind falls into the default branch and throws UnsupportedOperationException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlHelper.java:954
}
}
else {
for ( int i = 0; i < length; i++ ) {
final Object arrayElement = Array.get( value, i );
if ( arrayElement == null ) {
appender.append( NULL_TAG );
}
else {
appender.append( START_TAG );
convertedBasicValueToString( appender, arrayElement, options, elementJavaType, elementJdbcType );
appender.append( END_TAG );
}
}
}
}
break;
default:
throw new UnsupportedOperationException( "Unsupported JdbcType nested in struct: " + jdbcType );
}
}
private static int getSelectableMapping(
EmbeddableMappingType embeddableMappingType,
String name) {
final int selectableIndex = embeddableMappingType.getSelectableIndex( name );
if ( selectableIndex == -1 ) {
throw new IllegalArgumentException(
String.format(
"Could not find selectable [%s] in embeddable type [%s] for XML processing.",
name,
embeddableMappingType.getMappedJavaType().getJavaTypeClass().getName()
)
);
}
return selectableIndex;
}View on GitHub (pinned to fad1729dce)
Solutions
- Map the nested value as a plain String attribute and serialize it in application code.
- Move the exotic value out of the aggregate to its own column.
- Upgrade Hibernate and re-test: the supported set grows across versions.
- For custom JdbcTypes, contribute support upstream or pre-convert to a supported type.
Example fix
// before
@Embeddable
public class Doc {
String title;
@JdbcTypeCode(SqlTypes.JSON)
Map<String, Object> meta; // -> Unsupported JdbcType nested in struct
}
// after: store the nested JSON as a string inside the aggregate
@Embeddable
public class Doc {
String title;
String metaJson; // serialize meta with Jackson yourself
} Defensive patterns
Strategy: validation
Validate before calling
static final Set<Integer> NESTED_OK = Set.of(
SqlTypes.VARCHAR, SqlTypes.CHAR, SqlTypes.INTEGER, SqlTypes.BIGINT,
SqlTypes.DECIMAL, SqlTypes.DATE, SqlTypes.TIMESTAMP, SqlTypes.VARBINARY,
SqlTypes.UUID, SqlTypes.ARRAY /* ... */);
static void assertNestedTypesSupported(EmbeddableMappingType t) {
t.forEachSelectable((i, s) -> {
if (!NESTED_OK.contains(s.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode())) {
throw new IllegalStateException("Unsupported nested JDBC type: " + s);
}
});
} Try / catch
try {
session.persist(person);
} catch (UnsupportedOperationException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("Unsupported JdbcType nested in struct")) {
throw new DataMappingException("Aggregate nests an unsupported JDBC type", ex);
}
throw ex;
} Prevention
- Do not embed JSON, SQLXML, geometry, or vector values inside XML/struct aggregates; store them as strings or separate columns.
- Review aggregate field types in a startup check against the supported set.
- Re-test aggregates after adding custom JdbcTypes to fields.
When it happens
Trigger: Persisting an entity whose XML or struct aggregate embeddable contains a field of an unsupported nested JdbcType, e.g. @JdbcTypeCode(SqlTypes.JSON), a nested SQLXML field, a raw STRUCT, spatial geometry (SqlTypes.GEOMETRY), or a vector type.
Common situations: Composing document types (JSON inside XML), adding spatial or vector fields to existing aggregate embeddables, custom JdbcTypes not covered by the switch.
Related errors
- Support for attribute mapping type not yet implemented:
- Could not instantiate named strategy class [%s]
- Could not locate root element
- Unable to perform unmarshalling at line number {} and column
- Dialect does not support structured array types: ${dialectCl
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/4c729b9a6ad832bb.
Report an issue: GitHub.