hibernate/hibernate-orm · error · CoercionException
Cannot coerce Float value `%s` to Byte : not a whole number
Error message
Cannot coerce Float value `%s` to Byte : not a whole number
What it means
Hibernate throws this CoercionException when a Float with a fractional part is coerced to Byte. CoercionHelper.toByte(Float) runs isWholeNumber(value) first; values like 2.5f fail immediately. It is invoked from ByteJavaType.coerce when a Float value reaches a Byte-mapped attribute during persist/merge or parameter binding. Hibernate refuses lossy fractional-to-integral conversion rather than truncating.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:130
);
}
if ( value < Byte.MIN_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Double value `%s` to Byte : underflow",
value
)
);
}
return value.byteValue();
}
public static Byte toByte(Float value) {
if ( ! isWholeNumber( value ) ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Float value `%s` to Byte : not a whole number",
value
)
);
}
if ( value > Byte.MAX_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Float value `%s` to Byte : overflow",
value
)
);
}
View on GitHub (pinned to fad1729dce)
Solutions
- Round and narrow explicitly when truncation is fine: `(byte) Math.round(f)` after a range check; otherwise change the attribute type to Float.
- Fix the producer to emit integral types (Integer/Byte) for integral fields.
- Validate incoming Numbers at the boundary: whole-number plus range checks before Session calls.
- Consider an AttributeConverter<Float,Byte> to centralize rounding policy.
Example fix
// before float progress = uiSlider.getValue(); // e.g. 2.5f job.setProgress(progress); // Byte 'progress' -> "not a whole number" // after job.setProgress((byte) Math.round(progress)); // or declare progress as Float if fractional progress is meaningful
Defensive patterns
Strategy: validation
Validate before calling
Float f = uiValue;
if (f != Math.rint(f)) throw new IllegalArgumentException("value must be whole: " + f);
if (f < Byte.MIN_VALUE || f > Byte.MAX_VALUE) throw new IllegalArgumentException("out of byte range: " + f);
entity.setCode((byte) (int) f); Type guard
static boolean isWhole(Float f) { return f != null && !f.isNaN() && !f.isInfinite() && f == Math.rint(f); } Try / catch
catch CoercionException at the service boundary and translate to a 400 with the field name; deterministic — never retry.
Prevention
- Convert UI float outputs (sliders, gauges) to int at the presentation boundary.
- Keep integral entity fields typed byte/short/int end to end; don't accept Number in setters.
- Add tests with 0.5f increments for integral fields.
When it happens
Trigger: `ByteJavaType.coerce(2.5f)` — assigning a Float literal or computed float to a Byte/byte entity property, or `setParameter("b", 1.1f)` against a Byte path; typical when math libraries or UI layers hand back Floats for integral code fields.
Common situations: Android/Swing UI sliders returning Float progress into tinyint Byte fields; float-based math (weights 0.5f multipliers) feeding code columns; legacy APIs typed as Float; refactor of an attribute from Float to Byte while call sites still pass floats.
Related errors
- Cannot coerce Double value `%s` to Byte : not a whole number
- Cannot coerce Float value `%s` to Byte : overflow
- Cannot coerce Float value `%s` to Byte : underflow
- Cannot coerce Float value `%s` as Short : not a whole number
- Unable to coerce Float value `%s` to Integer: not a whole nu
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/70aaf85e39fd305c.
Report an issue: GitHub.