hibernate/hibernate-orm · error · CoercionException
Cannot coerce Long value `%s` to Byte : overflow
Error message
Cannot coerce Long value `%s` to Byte : overflow
What it means
Hibernate throws this CoercionException when a Long value must be narrowed to Byte (range -128..127) and it exceeds 127. It originates from CoercionHelper.toByte(Long), called by ByteJavaType.coerce when a Long-typed value is supplied for a Byte-mapped attribute. Hibernate 6 deliberately rejects lossy narrowing instead of truncating like a Java cast would; the message includes the offending value. This is a mapping/data contract problem, not a transient failure.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:72
);
}
if ( value < Byte.MIN_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Integer value `%s` to Byte : underflow",
value
)
);
}
return value.byteValue();
}
public static Byte toByte(Long value) {
if ( value > Byte.MAX_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Long value `%s` to Byte : overflow",
value
)
);
}
if ( value < Byte.MIN_VALUE ) {
throw new CoercionException(
String.format(
Locale.ROOT,
"Cannot coerce Long value `%s` to Byte : underflow",
value
)
);
}
View on GitHub (pinned to fad1729dce)
Solutions
- Align the attribute type with the value domain (Byte -> Long/Integer), or narrow explicitly after checking range (`longValue.byteValue()` only when -128..127).
- Convert the source value to Long-correct type at the boundary: fix the DTO/deserializer so the field is a Byte/Integer, not Long.
- Use an AttributeConverter<Long,Byte> if the narrowing is intentional, making the contract explicit.
- Validate incoming longs against the byte range at the API/import boundary and reject oversized values early.
Example fix
// before
Map<String,Object> props = new HashMap<>();
props.put("code", 999L); // Long
session.persist(dynamicEntity); // Byte-mapped 'code' -> CoercionException: overflow
// after
props.put("code", (byte) clampToByteRange(999L));
// or change attribute/column from tinyint to a wider type Defensive patterns
Strategy: validation
Validate before calling
Long v = (Long) rawValue;
if (v < Byte.MIN_VALUE || v > Byte.MAX_VALUE) throw new IllegalArgumentException("out of byte range: " + v);
entity.setCode(v.byteValue()); Type guard
static boolean fitsInByte(Long v) { return v != null && v >= (long) Byte.MIN_VALUE && v <= (long) Byte.MAX_VALUE; } Try / catch
try { session.persist(entity); } catch (org.hibernate.type.descriptor.java.CoercionException e) { throw new BadRequestException("numeric field out of range", e); } Prevention
- Type DTO fields as Byte/Integer instead of Long when the domain is a small code.
- Configure Jackson to use int-sized types (DeserializationFeature.USE_LONG_FOR_INTS off) unless needed.
- Never reuse Long ids/counters for tinyint-mapped fields.
- Test writes with boundary values 127/128/-128/-129 on Long paths.
When it happens
Trigger: A Byte/byte entity attribute receives a Long > 127: `entity.setFlag(someLongValue)` where the setter accepts Number/Object, or binding a long query parameter against a Byte-typed path (`setParameter("b", 300L)`), or Session.merge of a detached graph whose Byte field actually holds a Long (e.g. deserialized from JSON with BigInteger/Long ids).
Common situations: Copy DTOs where JSON numbers deserialize as Long (Jackson with USE_LONG_FOR_INTS, or values above int range) onto Byte fields; reusing id-like Long counters for small code fields; Hibernate 5 -> 6 upgrades where oversized values previously truncated silently; MySQL unsigned TINYINT holding 128..255 read back as a wider integer then re-persisted into a Byte attribute.
Related errors
- Cannot coerce Integer value `%s` to Byte : underflow
- Cannot coerce Long value `%s` to Byte : underflow
- Cannot coerce Double value `%s` to Byte : overflow
- Cannot coerce Float value `%s` to Byte : overflow
- Cannot coerce Integer value `%s` as Short : overflow
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/553c3e0437efad03.
Report an issue: GitHub.