{"record":{"id":"cf1dd8ffad5cf623","repo":"hibernate/hibernate-orm","slug":"cannot-coerce-long-value-s-to-byte-underflow","errorCode":null,"errorMessage":"Cannot coerce Long value `%s` to Byte : underflow","messagePattern":"Cannot coerce Long 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":82,"sourceCode":"\t\t\t);\n\t\t}\n\n\t\treturn value.byteValue();\n\t}\n\n\tpublic static Byte toByte(Long value) {\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 Long 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 Long 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(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","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L64-L100","documentation":"Hibernate throws this CoercionException when a Long value being narrowed to Byte falls below -128. Thrown from CoercionHelper.toByte(Long) via ByteJavaType.coerce during persist/update/merge or parameter binding on a Byte-mapped attribute. It is the underflow twin of the overflow check directly above it in the same method; the message carries the offending value. The intent is fail-fast rejection of lossy narrowing conversions in Hibernate 6.","triggerScenarios":"`ByteJavaType.coerce(value)` invoked with a Long < -128: assigning a negative Long to a byte/Byte entity field through a loosely typed setter, merging a detached entity whose Byte property was populated from a Long variable, or binding a long literal below -128 to a Byte-typed query parameter.","commonSituations":"Negative sentinel values (-1L, -999L) used as status/flag codes pushed into tinyint-mapped Byte fields; arithmetic on longs (timestamps deltas, hash codes) feeding a Byte field; data-migration jobs reading wide numeric columns into Byte attributes; upgrade to Hibernate 6 exposing previously silent truncation.","solutions":["Change the attribute or the producing code so types match: declare the field Long/Integer, or convert the long to byte explicitly after a -128..127 check.","Stop using out-of-range sentinels; store -1 style codes in a properly sized column (SMALLINT/INT) instead of TINYINT/Byte.","Add an AttributeConverter if deliberate narrowing is required, encoding the policy in one place.","Guard at the boundary: validate that any Number destined for a Byte field is within byte range before calling Session APIs."],"exampleFix":"// before\nlong errorCode = computeCode();   // e.g. -500\nmeter.setCode(errorCode);         // Byte 'code' property -> CoercionException: underflow\n\n// after\nif (errorCode < Byte.MIN_VALUE || errorCode > Byte.MAX_VALUE) {\n    throw new IllegalArgumentException(\"code out of byte range: \" + errorCode);\n}\nmeter.setCode((byte) errorCode);","handlingStrategy":"validation","validationCode":"if (longValue < Byte.MIN_VALUE || longValue > Byte.MAX_VALUE) {\n    throw new IllegalArgumentException(\"code out of byte range: \" + longValue);\n}\nentity.setCode((byte) longValue);","typeGuard":"static boolean fitsInByte(long v) { return v >= -128L && v <= 127L; }","tryCatchPattern":"catch (CoercionException e) when persisting: map to a 422/400 response naming the field; never retry — the failure is deterministic.","preventionTips":["Avoid negative sentinel longs for byte-sized status fields.","Keep unit tests covering negative boundary values (-128/-129).","Run a data audit when narrowing any column type before switching the attribute."],"tags":["hibernate","type-coercion","byte","underflow","numeric-range"],"backgroundTag":"numeric-overflow-underflow","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}