hibernate/hibernate-orm · error · CoercionException
Cannot coerce Double value `%s` to Byte : overflow
Error message
Cannot coerce Double value `%s` to Byte : overflow
What it means
Hibernate throws this CoercionException when a whole-number Double must be narrowed to Byte and exceeds 127. CoercionHelper.toByte(Double) passes the isWholeNumber check but then fails `value > Byte.MAX_VALUE` (note: comparing Double to Byte.MAX_VALUE widens the byte constant). Reached via ByteJavaType.coerce for Double values supplied to Byte-mapped attributes. Hibernate 6 rejects the lossy narrowing instead of truncating the double as a Java cast would.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:106
);
}
return value.byteValue();
}
public static Byte toByte(Double value) {
if ( ! isWholeNumber( value ) ) {
throw new CoercionException(
String.format(
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
)
);
}
View on GitHub (pinned to fad1729dce)
Solutions
- Verify the value domain: if values above 127 are legitimate, widen the attribute/column (Byte -> Integer/Short, TINYINT -> SMALLINT/INT).
- If narrowing is intended, validate and convert explicitly: check -128..127 then `(byte) doubleValue`.
- Fix upstream producers that emit Double for integral quantities (change DTO field types to Integer).
- Add an AttributeConverter<Double,Byte> to centralize an intentional rounding+narrowing policy.
Example fix
// before
Double score = analytics.scoreFor(id); // e.g. 150.0
player.setSkill(score); // Byte 'skill' -> overflow
// after
int i = (int) Math.round(score);
if (i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) throw new IllegalArgumentException("skill too large: " + i);
player.setSkill((byte) i); Defensive patterns
Strategy: validation
Validate before calling
double d = score;
if (d < Byte.MIN_VALUE || d > Byte.MAX_VALUE) throw new IllegalArgumentException("score out of byte range: " + d);
if (d != Math.rint(d)) throw new IllegalArgumentException("score must be whole: " + d);
entity.setScore((byte) (long) d); Type guard
static boolean fitsInByte(double d) { return d >= -128.0 && d <= 127.0 && d == Math.rint(d) && !Double.isInfinite(d); } Try / catch
catch CoercionException around session ops and translate to a user-facing range error; do not retry.
Prevention
- Do not let Double-typed scores feed tinyint columns without an explicit clamp+round.
- Widen the column when the legitimate domain exceeds ±127.
- Check for unit mismatches (percent 0-1000 stored in a 0-100 field) when this appears in production.
When it happens
Trigger: `ByteJavaType.coerce(130.0)` — assigning a whole Double like 130.0 or 1e3 to a Byte/byte entity field, or binding such a value as a query parameter against a Byte-typed path; common when Double-typed counters or scores feed a tinyint-mapped property.
Common situations: Scores/ratings stored as tinyint Byte but computed as Double and exceeding the range; Jackson-deserialized decimals (e.g. "128.0") landing on Byte fields; Excel/CSV imports that render all numbers as doubles; Hibernate 5 -> 6 upgrades where the old version silently truncated.
Related errors
- Cannot coerce Long value `%s` to Byte : overflow
- Cannot coerce Double value `%s` to Byte : not a whole number
- Cannot coerce Double value `%s` to Byte : underflow
- Cannot coerce Float value `%s` to Byte : overflow
- Cannot coerce Short value `%s` to Byte : overflow
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/24df8eaa673ef007.
Report an issue: GitHub.