{"record":{"id":"c5cef95aa669f2e2","repo":"hibernate/hibernate-orm","slug":"cannot-coerce-double-value-s-to-byte-underflo","errorCode":null,"errorMessage":"Cannot coerce Double value `%s` to Byte : underflow","messagePattern":"Cannot coerce Double value `(.+?)` to Byte : underflow","errorType":"exception","errorClass":"CoercionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java","lineNumber":116,"sourceCode":"\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Cannot coerce Double value `%s` to Byte : not a whole number\",\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( value > Byte.MAX_VALUE ) {\n\t\t\tthrow new CoercionException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Cannot coerce Double value `%s` to Byte : overflow\",\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( value < Byte.MIN_VALUE ) {\n\t\t\tthrow new CoercionException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Cannot coerce Double value `%s` to Byte : underflow\",\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\treturn value.byteValue();\n\t}\n\n\tpublic static Byte toByte(Float value) {\n\t\tif ( ! isWholeNumber( value ) ) {\n\t\t\tthrow new CoercionException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Cannot coerce Float value `%s` to Byte : not a whole number\",\n\t\t\t\t\t\t\tvalue","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L98-L134","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nDouble delta = oldReading - newReading;  // e.g. -500.0\nsensor.setDelta(delta);                  // Byte field -> underflow\n\n// after\nlong l = Math.round(delta);\nif (l < Byte.MIN_VALUE || l > Byte.MAX_VALUE) {\n    sensor.setDelta(null);               // or throw a domain exception\n} else {\n    sensor.setDelta((byte) l);\n}","handlingStrategy":"validation","validationCode":"long l = Math.round(delta);\nif (l < Byte.MIN_VALUE || l > Byte.MAX_VALUE) throw new IllegalArgumentException(\"delta out of byte range: \" + l);\nentity.setDelta((byte) l);","typeGuard":"static boolean fitsInByte(Double d) { return d != null && d == Math.rint(d) && d >= -128.0 && d <= 127.0; }","tryCatchPattern":"try { session.merge(e); } catch (CoercionException ex) { log field + value; return validation error; }","preventionTips":["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."],"tags":["hibernate","type-coercion","byte","double","underflow"],"backgroundTag":"numeric-overflow-underflow","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}