hibernate/hibernate-orm · error · CoercionException
Cannot coerce Float value `%s` to Double : underflow
Error message
Cannot coerce Float value `%s` to Double : underflow
What it means
Thrown by CoercionHelper.toDouble(Float) when floatValue < (float) Double.MIN_VALUE. Double.MIN_VALUE is the smallest positive double (~4.9e-324) and casting it to float yields 0.0f, so the condition degenerates to 'floatValue < 0.0f': in this Hibernate version every negative Float fails Float-to-Double widening with 'underflow', even though all negative floats fit comfortably in a double. This is a bug in the guard, not a genuine range problem with your data.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:356
}
public static BigInteger toBigInteger(BigDecimal value) {
return coerceWrappingError( value::toBigIntegerExact );
}
public static Double toDouble(Float floatValue) {
if ( floatValue > (float) Double.MAX_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Float value `%s` to Double : overflow",
floatValue
)
);
}
if ( floatValue < (float) Double.MIN_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Float value `%s` to Double : underflow",
floatValue
)
);
}
return (double) floatValue;
}
public static Double toDouble(BigInteger value) {
return coerceWrappingError( value::doubleValue );
}
public static Double toDouble(BigDecimal value) {
return coerceWrappingError( value::doubleValue );
}View on GitHub (pinned to fad1729dce)
Solutions
- Widen the value yourself before Hibernate sees it: pass Double.valueOf(f) or (double) f instead of the Float
- Change float fields, variables, and parameters to double so the Float overload is never exercised
- Upgrade hibernate-core to a release where the negative-float underflow check is corrected
- Interim workaround: catch CoercionException and re-coerce from the original value
Example fix
// before
query.setParameter("amount", -1.5f); // Float -> CoercionException: underflow
// after
query.setParameter("amount", -1.5); // double literal, Float coercion path avoided Defensive patterns
Strategy: type-guard
Validate before calling
// pre-widen every Float before Hibernate sees it
static Object widenFloats(Object v) {
return v instanceof Float f ? f.doubleValue() : v;
} Type guard
static boolean safeForDoubleCoercion(Object v) {
// on affected versions every negative Float trips the underflow guard
return !(v instanceof Float f) || !(f < 0f);
} Try / catch
try {
return query.getSingleResult();
} catch (CoercionException e) {
if (e.getMessage().contains("underflow") && original instanceof Float f) {
return rebind(f.doubleValue()); // widen and retry once
}
throw e;
} Prevention
- Standardize on double (not float) for entity fields and query parameters
- Grep the codebase for f-suffix literals passed into setParameter
- Track the Hibernate release notes and upgrade once the underflow fix ships
When it happens
Trigger: Binding any negative Float where a double is expected: query.setParameter("delta", -1.5f) on a Double-typed attribute or path; an AttributeConverter or HQL coercion path that feeds a boxed Float into CoercionHelper.toDouble(Float).
Common situations: Entity fields typed Double receiving float literals (the f suffix) or Float values from older APIs; codebases mixing float and double after a schema or entity refactor; failures that appear after upgrading to Hibernate 6.x coercion-based binding.
Related errors
- Cannot coerce Float value `%s` to Byte : underflow
- Unable to coerce Double Float `%s` as BigInteger: not a whol
- Cannot coerce value '%s' [%s] to Float
- Cannot coerce Integer value `%s` to Byte : underflow
- Cannot coerce Long value `%s` to Byte : underflow
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/175792b7fee02f21.
Report an issue: GitHub.