hibernate/hibernate-orm · error · CoercionException
Cannot coerce Double value `%s` to Byte : underflow
Error message
Cannot coerce Double value `%s` to Byte : underflow
What it means
Hibernate throws this CoercionException when a whole-number Double is narrowed to Byte and is below -128. CoercionHelper.toByte(Double) checks isWholeNumber, then the upper bound, then fails `value < Byte.MIN_VALUE`. It is the Double underflow counterpart reached from ByteJavaType.coerce. The offending value is embedded in the message, and the failure is deterministic — retrying never helps.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:116
Locale.ROOT,
"Cannot coerce Double value `%s` to Byte : not a whole number",
value
)
);
}
if ( value > Byte.MAX_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Double value `%s` to Byte : overflow",
value
)
);
}
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",
valueView on GitHub (pinned to fad1729dce)
Solutions
- Match the attribute type to the value domain (Byte -> Double/Integer/Long) or pre-validate and narrow explicitly after a -128..127 check.
- Correct the upstream computation that produces out-of-range magnitudes (unit or sign errors).
- Reject out-of-range values at the import/API boundary with a clear domain error.
- If intentional, encode narrowing in an AttributeConverter instead of relying on implicit coercion.
Example fix
// before
Double delta = oldReading - newReading; // e.g. -500.0
sensor.setDelta(delta); // Byte field -> underflow
// after
long l = Math.round(delta);
if (l < Byte.MIN_VALUE || l > Byte.MAX_VALUE) {
sensor.setDelta(null); // or throw a domain exception
} else {
sensor.setDelta((byte) l);
} Defensive patterns
Strategy: validation
Validate before calling
long l = Math.round(delta);
if (l < Byte.MIN_VALUE || l > Byte.MAX_VALUE) throw new IllegalArgumentException("delta out of byte range: " + l);
entity.setDelta((byte) l); Type guard
static boolean fitsInByte(Double d) { return d != null && d == Math.rint(d) && d >= -128.0 && d <= 127.0; } Try / catch
try { session.merge(e); } catch (CoercionException ex) { log field + value; return validation error; } Prevention
- Validate magnitude AND sign of computed doubles before narrowing.
- Prefer int/long arithmetic for counters destined for byte fields.
- Alert on range violations rather than silently clamping in production paths.
When it happens
Trigger: Assigning a whole Double < -128 (e.g. -200.0, -1e5) to a Byte/byte entity attribute, or binding it as a parameter to a Byte-typed query path; e.g. `entity.setOffset(-300.0)` where offset is Byte.
Common situations: Negative Double deltas or error scores stored into tinyint Byte fields; financial/scientific computations emitting large-magnitude negative doubles; unit mismatches (milliseconds vs seconds) inflating values past the byte range; upgrading Hibernate and losing silent truncation.
Related errors
- Cannot coerce Integer value `%s` to Byte : underflow
- Cannot coerce Long value `%s` to Byte : underflow
- Cannot coerce Double value `%s` to Byte : not a whole number
- Cannot coerce Double value `%s` to Byte : overflow
- Cannot coerce Float value `%s` to Byte : underflow
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c5cef95aa669f2e2.
Report an issue: GitHub.