hibernate/hibernate-orm · error · CoercionException
Unable to coerce Float value `%s` to Integer: not a whole nu
Error message
Unable to coerce Float value `%s` to Integer: not a whole number
What it means
Hibernate throws this CoercionException when a Float with a fractional part is coerced to Integer. CoercionHelper.toInteger(Float) first checks isWholeNumber(floatValue); values like 3.14f fail before any narrowing occurs. It is invoked from IntegerJavaType.coerce when a Float value is assigned to or bound against an Integer-mapped attribute. Hibernate deliberately blocks lossy fractional-to-integral coercion rather than silently truncating.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:248
}
public static Integer toInteger(Double doubleValue) {
if ( ! isWholeNumber( doubleValue ) ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Unable to coerce Double value `%s` to Integer: not a whole number",
doubleValue
)
);
}
return toInteger( doubleValue.longValue() );
}
public static Integer toInteger(Float floatValue) {
if ( ! isWholeNumber( floatValue ) ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Unable to coerce Float value `%s` to Integer: not a whole number",
floatValue
)
);
}
return toInteger( floatValue.longValue() );
}
public static Integer toInteger(BigInteger value) {
return coerceWrappingError( value::intValueExact );
}
public static Integer toInteger(BigDecimal value) {
return coerceWrappingError( value::intValueExact );
}View on GitHub (pinned to fad1729dce)
Solutions
- Round deliberately when truncation is fine: `Math.round(f)` then int assignment; otherwise store as FLOAT/DOUBLE.
- Fix producers to emit integral types for count-like fields.
- Validate incoming Numbers are whole before mapping onto Integer attributes.
- Where a fixed policy exists, centralize it in an AttributeConverter<Float,Integer>.
Example fix
// before Float progress = reportEngine.completion(); // e.g. 66.6f report.setProgress(progress); // Integer 'progress' -> "not a whole number" // after report.setProgress(Math.round(progress)); // or declare progress as Float with a FLOAT column
Defensive patterns
Strategy: validation
Validate before calling
Float f = engine.completion();
if (f != Math.rint(f)) throw new IllegalArgumentException("progress must be whole: " + f);
report.setProgress(Math.round(f)); Type guard
static boolean isWholeFloat(Float f) { return f != null && !f.isNaN() && !f.isInfinite() && f == Math.rint(f); } Try / catch
catch CoercionException and translate to a validation error naming the field; deterministic — no retry.
Prevention
- Convert float progress/ratio outputs to int at the producing layer.
- Map genuinely fractional metrics to FLOAT/DOUBLE columns.
- Reject NaN/Infinity floats early in numeric pipelines.
When it happens
Trigger: `IntegerJavaType.coerce(3.14f)` — e.g. `entity.setQuantity(floatComputedValue)` on an int/Integer attribute, or `setParameter("qty", 2.9f)` against an Integer-typed path; typical with UI components or math APIs returning Float for counts.
Common situations: Slider/progress Float values from UI toolkits persisted into INTEGER columns; float-based math feeding quantity/count fields; legacy Float-typed interfaces; NoSQL or analytics sources yielding floats for integral data.
Related errors
- Cannot coerce Float value `%s` to Byte : not a whole number
- Cannot coerce Float value `%s` as Short : not a whole number
- Unable to coerce Double value `%s` to Integer: not a whole n
- Unable to coerce Float value `%s` as Integer: not a whole nu
- Cannot coerce Double value `%s` to Byte : not a whole number
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a32350f2275b0101.
Report an issue: GitHub.