{"record":{"id":"24df8eaa673ef007","repo":"hibernate/hibernate-orm","slug":"cannot-coerce-double-value-s-to-byte-overflow","errorCode":null,"errorMessage":"Cannot coerce Double value `%s` to Byte : overflow","messagePattern":"Cannot coerce Double value `(.+?)` to Byte : overflow","errorType":"exception","errorClass":"CoercionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java","lineNumber":106,"sourceCode":"\t\t\t);\n\t\t}\n\n\t\treturn value.byteValue();\n\t}\n\n\tpublic static Byte toByte(Double 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 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","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L88-L124","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"// before\nDouble score = analytics.scoreFor(id);  // e.g. 150.0\nplayer.setSkill(score);                 // Byte 'skill' -> overflow\n\n// after\nint i = (int) Math.round(score);\nif (i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) throw new IllegalArgumentException(\"skill too large: \" + i);\nplayer.setSkill((byte) i);","handlingStrategy":"validation","validationCode":"double d = score;\nif (d < Byte.MIN_VALUE || d > Byte.MAX_VALUE) throw new IllegalArgumentException(\"score out of byte range: \" + d);\nif (d != Math.rint(d)) throw new IllegalArgumentException(\"score must be whole: \" + d);\nentity.setScore((byte) (long) d);","typeGuard":"static boolean fitsInByte(double d) { return d >= -128.0 && d <= 127.0 && d == Math.rint(d) && !Double.isInfinite(d); }","tryCatchPattern":"catch CoercionException around session ops and translate to a user-facing range error; do not retry.","preventionTips":["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."],"tags":["hibernate","type-coercion","byte","double","overflow"],"backgroundTag":"numeric-overflow-underflow","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}