hibernate/hibernate-orm · error · UnsupportedOperationException

Unwrap strategy not known for this Java type: " + getTypeNam

Error message

Unwrap strategy not known for this Java type: " + getTypeName()

What it means

EmbeddableAggregateJavaType only unwraps a value to its own embeddable class — conversion to String, byte[] or driver types is the JdbcType's job (the format mapper serializes during binding). Calling unwrap() with any target type other than the embeddable's class throws UnsupportedOperationException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EmbeddableAggregateJavaType.java:75

		}
		else {
			// Otherwise use json by default for now
			final var descriptor = context.getJdbcType( SqlTypes.JSON );
			if ( descriptor != null ) {
				return descriptor;
			}
		}
		throw new JdbcTypeRecommendationException(
				"Could not determine recommended JdbcType for `" + getTypeName() + "`"
		);
	}

	@Override
	public <X> X unwrap(T value, Class<X> type, WrapperOptions options) {
		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()
			);
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Unwrap only to the embeddable's own class and let the JdbcType (e.g. JsonJdbcType) perform serialization
  2. When you need a String outside the binder, serialize explicitly via the FormatMapper (Jackson/Gson)
  3. For full manual control, map an AttributeConverter from the embeddable to String instead

Example fix

// before
String json = embeddableJavaType.unwrap(address, String.class, options); // throws

// after
Address a = embeddableJavaType.unwrap(address, Address.class, options);
String json = formatMapper.toString(a, embeddableJavaType, options); // serialization is the mapper's job
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean canUnwrap(JavaType<?> jt, Class<?> target) {
    return target.isAssignableFrom(jt.getJavaTypeClass()); // aggregate embeddables: own class only
}

Type guard

static boolean unwrapSupported(JavaType<?> javaType, Class<?> target) {
    return target.isAssignableFrom(javaType.getJavaTypeClass());
}

Try / catch

try {
    X v = javaType.unwrap(value, target, options);
} catch (UnsupportedOperationException e) {
    // rethrow with context: embeddable + requested target, so callers know serialization
    // belongs to the JdbcType/FormatMapper, not unwrap()
    throw new UnsupportedOperationException("unwrap to " + target + " unsupported for "
        + javaType.getJavaTypeClass().getName(), e);
}

Prevention

When it happens

Trigger: Binding an aggregate embeddable to a native-query parameter expecting a String; custom JdbcTypes or converters calling javaType.unwrap(value, String.class, options); generic serialization code that assumes unwrap-to-String works for every JavaType.

Common situations: Porting Hibernate 5 UserType contracts to the 6.x JavaType/JdbcType split; custom dialect integrations; copying unwrap patterns from StringJavaType which supports broader targets.

Related errors


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