hibernate/hibernate-orm · error · UnsupportedOperationException
Wrap strategy not known for this Java type: " + getTypeName(
Error message
Wrap strategy not known for this Java type: " + getTypeName()
What it means
The mirror of unwrap: wrap() accepts only null or instances of the embeddable class itself. Reading an aggregate column yields the deserialized embeddable; handing wrap() anything else — a JSON String, a Map, a driver PGobject — throws UnsupportedOperationException because the JavaType does no parsing.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EmbeddableAggregateJavaType.java:90
if ( type.isAssignableFrom( getJavaTypeClass() ) ) {
return type.cast( value );
}
throw new UnsupportedOperationException(
"Unwrap strategy not known for this Java type: " + getTypeName()
);
}
@Override
public <X> T wrap(X value, WrapperOptions options) {
if ( value == null ) {
return null;
}
else {
final var javaTypeClass = getJavaTypeClass();
if ( javaTypeClass.isInstance( value ) ) {
return javaTypeClass.cast( value );
}
throw new UnsupportedOperationException(
"Wrap strategy not known for this Java type: " + getTypeName()
);
}
}
@Override
public String toString() {
return "BasicJavaType(" + getTypeName() + ")";
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Pass the deserialized embeddable instance (or null), never its serialized form
- Deserialize first with the FormatMapper: mapper.fromString(rs.getString(...), javaType, options)
- Let the standard JsonJdbcType extractor drive hydration so wrap() only ever sees typed objects
Example fix
// before
Address a = embeddableJavaType.wrap(rs.getString("address"), options); // String is not an Address -> throws
// after
Address a = formatMapper.fromString(rs.getString("address"), embeddableJavaType, options);
// or simply rely on the annotated attribute's own JsonJdbcType binding Defensive patterns
Strategy: type-guard
Validate before calling
static Object safeWrap(JavaType<?> jt, Object raw, WrapperOptions options) {
if (raw == null || jt.getJavaTypeClass().isInstance(raw)) {
return jt.wrap(jt.getJavaTypeClass().cast(raw), options);
}
return null; // or deserialize via FormatMapper first
} Type guard
static boolean wrapSupported(JavaType<?> jt, Object value) {
return value == null || jt.getJavaTypeClass().isInstance(value);
} Try / catch
try {
T v = javaType.wrap(raw, options);
} catch (UnsupportedOperationException e) {
// deserialize the JSON yourself, then hand the typed object back
T v = formatMapper.fromString((String) raw, javaType, options);
} Prevention
- Hydrate aggregate columns through FormatMapper.fromString, never JavaType.wrap
- Keep custom extractors aligned with the JdbcType contract
- Cover wrap paths in custom-type contract tests
When it happens
Trigger: Custom result-set extraction calling javaType.wrap(rs.getString(...), options); converters feeding pre-serialized JSON back into wrap; hydrating driver-specific JSONB objects directly.
Common situations: Hand-written JDBC readers for JSON columns; migration of legacy Hibernate 5 UserType code; generic hydration frameworks that try wrap() first with whatever object they hold.
Related errors
- Unwrap strategy not known for this Java type: " + getTypeNam
- Wrap strategy not known for this Java type: " + getTypeName(
- Embeddable class not found: {}
- component: {} property not found: {}
- component type [{}] specifies {} properties for the instanti
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/99ad452d1d1cb7fb.
Report an issue: GitHub.