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

  1. Pass the deserialized embeddable instance (or null), never its serialized form
  2. Deserialize first with the FormatMapper: mapper.fromString(rs.getString(...), javaType, options)
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/99ad452d1d1cb7fb. Report an issue: GitHub.