hibernate/hibernate-orm · error · HibernateException

Unknown wrap conversion requested: " + conversionType.getNam

Error message

Unknown wrap conversion requested: " + conversionType.getName() + " to " + type.getTypeName()

What it means

AbstractJavaType.unknownWrap is the mirror of unknownUnwrap: JavaType.wrap(value, options) hit a source class the descriptor cannot convert into its represented type. Thrown when a value coming from JDBC (or another source) must be wrapped into the descriptor's Java type and no conversion exists.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractJavaType.java:94

	@Override
	public Comparator<T> getComparator() {
		return comparator;
	}

	@Override
	public String extractLoggableRepresentation(T value) {
		return (value == null) ? "null" : value.toString();
	}

	protected HibernateException unknownUnwrap(Class<?> conversionType) {
		throw new HibernateException(
				"Unknown unwrap conversion requested: " + type.getTypeName() + " to " + conversionType.getName()
		);
	}

	protected HibernateException unknownWrap(Class<?> conversionType) {
		throw new HibernateException(
				"Unknown wrap conversion requested: " + conversionType.getName() + " to " + type.getTypeName()
		);
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Broaden the custom JavaType's wrap() to cover the actual incoming classes (Number, String, java.util.Date, ...)
  2. Adjust the native query/addScalar typing so the retrieved class matches what the descriptor wraps
  3. Register/use a converter or a different descriptor that accepts the driver's actual class
  4. Check the dialect/driver version if the incoming class changed after an upgrade

Example fix

// before
@Override
public <X> Money wrap(X value, WrapperOptions options) {
    if (value instanceof String s) return Money.parse(s);
    return unknownWrap(value.getClass()); // driver sends BigDecimal
}
// after
@Override
public <X> Money wrap(X value, WrapperOptions options) {
    if (value instanceof String s) return Money.parse(s);
    if (value instanceof Number n) return Money.of(n);
    return unknownWrap(value.getClass());
}
Defensive patterns

Strategy: type-guard

Validate before calling

// when reading via native query + addScalar, confirm the driver's class is wrap-compatible
Object raw = resultSet.getObject(column);
if (!descriptorWraps(raw.getClass())) {
    raw = resultSet.getString(column); // fall back to a form the descriptor wraps
}

Type guard

// widen and check in a custom JavaType before delegating
static boolean canWrap(Object value) {
    return value == null || value instanceof String || value instanceof Number
        || value instanceof java.util.Date || value instanceof byte[];
}

Try / catch

try {
    return session.createNativeQuery("select amt from t", Money.class).getSingleResult();
} catch (HibernateException e) {
    if (String.valueOf(e.getMessage()).contains("Unknown wrap conversion requested")) {
        // the driver returned a class the descriptor lacks: map as String and parse in a converter
    } else throw e;
}

Prevention

When it happens

Trigger: A custom JavaType whose wrap() does not handle the concrete class of the incoming relational value - e.g. the driver returns java.math.BigInteger but the descriptor only wraps Integer; or reading a column through a descriptor registered for a different type.

Common situations: Driver/dialect returning unexpected JDBC classes (Oracle NUMBER as BigInteger, TIMESTAMP as oracle.sql.TIMESTAMP); custom JavaType with partial wrap() coverage; forcing a type on a native query result via addScalar(type) where the underlying value class differs.

Related errors


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