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

  1. Align the attribute type with the value domain (Byte -> Long/Integer), or narrow explicitly after checking range (`longValue.byteValue()` only when -128..127).
  2. Convert the source value to Long-correct type at the boundary: fix the DTO/deserializer so the field is a Byte/Integer, not Long.
  3. Use an AttributeConverter<Long,Byte> if the narrowing is intentional, making the contract explicit.
  4. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/553c3e0437efad03. Report an issue: GitHub.