{"record":{"id":"a8555bd2e43ccdd1","repo":"hibernate/hibernate-orm","slug":"cannot-coerce-integer-value-s-to-byte-underfl","errorCode":null,"errorMessage":"Cannot coerce Integer value `%s` to Byte : underflow","messagePattern":"Cannot coerce Integer 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":58,"sourceCode":"\t\t\t);\n\t\t}\n\n\t\treturn value.byteValue();\n\t}\n\n\tpublic static Byte toByte(Integer 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 Integer 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 Integer 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(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","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L40-L76","documentation":"Hibernate throws this CoercionException (a HibernateException subclass) when a Java Integer value must be narrowed to java.lang.Byte (range -128..127) and the value is below -128. It is thrown from CoercionHelper.toByte(Integer), reached via ByteJavaType.coerce(...) during persist/merge/saveOrUpdate or query-parameter binding when the value handed to a Byte-mapped attribute is an Integer that cannot be represented as a byte. Unlike silent Java narrowing casts, Hibernate 6 refuses lossy conversions and fails fast with the offending value in the message (the `%s` is the input value).","triggerScenarios":"Entity attribute declared `Byte`/`byte` (e.g. a tinyint column) but the code assigns an Integer below -128: `entity.setByteValue(-200)` where the setter takes Number/Object, or `session.createQuery(...).setParameter(\"b\", -200)` bound against a Byte-typed path. Also fires when a Map<String,Object> payload or dynamic-model value containing an Integer is funneled into a Byte attribute via ByteJavaType.coerce.","commonSituations":"JSON payloads deserialized by Jackson into Integer/Object fields then copied onto a Byte entity property; dynamic maps or CSV import feeds; switching an attribute from Integer to Byte without cleaning stored data; moving from Hibernate 5 (which narrowed silently) to Hibernate 6 (which validates); unsigned TINYINT columns on MySQL/MariaDB holding values 128..255 that map to negative/oversized integers.","solutions":["Fix the type mismatch at the source: either declare the entity attribute as Integer/Short to match the real value domain, or convert the value to byte before assignment (`(byte) intValue` or `intValue.byteValue()` after a range check).","If narrowing is intentional and out-of-range data is impossible-by-contract, add an explicit javax.persistence.AttributeConverter<Integer,Byte> that documents and performs the narrowing.","If out-of-range values are legitimate, change the column DDL (e.g. TINYINT -> SMALLINT/INT) and remap the attribute type accordingly.","Add a range guard (-128..127) in the setter or at the import boundary and reject/clamp bad values before they reach the Session."],"exampleFix":"// before\n@Entity class Meter {\n    Byte offset;              // tinyint column\n}\nmeter.setOffset(payloadValue); // payloadValue is Integer -200 -> CoercionException\n\n// after\n@Entity class Meter {\n    Integer offset;            // matches actual value domain\n}\n// or guard before assignment:\nif (payloadValue >= Byte.MIN_VALUE && payloadValue <= Byte.MAX_VALUE) {\n    meter.setOffset(payloadValue.byteValue());\n} else {\n    throw new IllegalArgumentException(\"offset out of byte range: \" + payloadValue);\n}","handlingStrategy":"validation","validationCode":"Integer v = payload.getByteField();\nif (v < Byte.MIN_VALUE || v > Byte.MAX_VALUE) {\n    throw new IllegalArgumentException(\"value out of byte range: \" + v);\n}\nentity.setByteField(v.byteValue());","typeGuard":"static boolean fitsInByte(Integer v) { return v != null && v >= Byte.MIN_VALUE && v <= Byte.MAX_VALUE; }","tryCatchPattern":"try { session.merge(entity); } catch (CoercionException e) { /* log offending value, reject the write */ } // CoercionException extends HibernateException","preventionTips":["Declare entity numeric attributes with the exact Java type the writers use; avoid Number/Object-typed setters for small integer fields.","Validate numeric ranges at the API/import boundary before values reach the Session.","When mapping tinyint columns, confirm no unsigned values > 127 can occur, or map to Short/Integer.","Add integration tests that persist edge values (-129, -128, 127, 128) against narrowed attributes."],"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"}