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

unwrap() on a FormatMapperBasedJavaType supports exactly two targets: the mapped Java class itself (identity cast) and String (produced via the format mapper). Requesting any other type — byte[], driver-specific classes, other wrappers — throws UnsupportedOperationException, because JDBC-specific conversion belongs to the JdbcType.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/FormatMapperBasedJavaType.java:74

				.toString( value, this, getWrapperOptions() );
	}

	@Override
	public T fromString(CharSequence string) {
		return getFormatMapper( typeConfiguration )
				.fromString( string, this, getWrapperOptions() );
	}

	@Override
	public <X> X unwrap(T value, Class<X> type, WrapperOptions options) {
		if ( type.isAssignableFrom( getJavaTypeClass() ) ) {
			return type.cast( value );
		}
		else if ( type == String.class ) {
			return type.cast( getFormatMapper( typeConfiguration )
					.toString( value, this, options ) );
		}
		throw new UnsupportedOperationException(
				"Unwrap strategy not known for this Java type: " + getTypeName()
		);
	}

	@Override
	public <X> T wrap(X value, WrapperOptions options) {
		final var javaTypeClass = getJavaTypeClass();
		if ( javaTypeClass.isInstance( value ) ) {
			return javaTypeClass.cast( value );
		}
		else if ( value instanceof String string ) {
			return getFormatMapper( typeConfiguration )
					.fromString( string, this, options );
		}
		throw new UnsupportedOperationException(
				"Wrap strategy not known for this Java type: " + getTypeName()
		);
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Request only the mapped class or String from unwrap
  2. Do JSON serialization via the format mapper, not unwrap
  3. Move JDBC-type conversion into your JdbcType's binder, which owns driver types

Example fix

// before
byte[] b = javaType.unwrap(payload, byte[].class, options); // throws

// after
String json = javaType.unwrap(payload, String.class, options);
byte[] b = json.getBytes(java.nio.charset.StandardCharsets.UTF_8);
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean unwrapTargetOk(JavaType<?> jt, Class<?> target) {
    return target.isAssignableFrom(jt.getJavaTypeClass()) || target == String.class;
}

Type guard

static <X> boolean formatMapperUnwrapSupported(JavaType<?> jt, Class<X> target) {
    return target == String.class || target.isAssignableFrom(jt.getJavaTypeClass());
}

Try / catch

try {
    X v = javaType.unwrap(value, target, options);
} catch (UnsupportedOperationException e) {
    String json = javaType.unwrap(value, String.class, options); // always-supported target
    // convert json yourself to the type you actually wanted
}

Prevention

When it happens

Trigger: Generic binder/converter code calling unwrap(value, byte[].class or PGobject.class, options); custom JdbcTypes expecting a driver type from the JavaType; code ported from descriptors like StringJavaType that unwrap to many targets.

Common situations: Porting Hibernate 5 UserType implementations; custom dialect integrations; binary JSON handling where code reads values as byte arrays.

Related errors


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