hibernate/hibernate-orm · error · CoercionException

Cannot coerce Float value `%s` to Byte : overflow

Error message

Cannot coerce Float value `%s` to Byte : overflow

What it means

Hibernate throws this CoercionException when a whole-number Float is narrowed to Byte and exceeds 127. In CoercionHelper.toByte(Float), after the isWholeNumber guard, `value > Byte.MAX_VALUE` fails (byte constant widened to float for the comparison). Reached via ByteJavaType.coerce for Float values on Byte-mapped attributes. It is a hard, deterministic mapping failure in Hibernate 6's stricter coercion model.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java:140

			);
		}

		return value.byteValue();
	}

	public static Byte toByte(Float value) {
		if ( ! isWholeNumber( value ) ) {
			throw new CoercionException(
					String.format(
							Locale.ROOT,
							"Cannot coerce Float value `%s` to Byte : not a whole number",
							value
					)
			);
		}

		if ( value > Byte.MAX_VALUE ) {
			throw new CoercionException(
					String.format(
							Locale.ROOT,
							"Cannot coerce Float value `%s` to Byte : overflow",
							value
					)
			);
		}

		if ( value < Byte.MIN_VALUE ) {
			throw new CoercionException(
					String.format(
							Locale.ROOT,
							"Cannot coerce Float value `%s` to Byte : underflow",
							value
					)
			);
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Widen the attribute and column if values legitimately exceed 127 (Byte -> Short/Integer, TINYINT -> SMALLINT).
  2. Narrow explicitly with validation: `int i = Math.round(f); if (i > 127 || i < -128) throw ...; (byte) i`.
  3. Fix upstream float producers to use integral types.
  4. Centralize intentional narrowing in an AttributeConverter.

Example fix

// before
Float adc = sensorReader.readAdc();    // e.g. 512.0f
pin.setThreshold(adc);                 // Byte 'threshold' -> overflow

// after
private static byte toByteRange(Float f) {
    int i = Math.round(f);
    if (i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) throw new IllegalArgumentException("ADC out of byte range: " + i);
    return (byte) i;
}
pin.setThreshold(toByteRange(adc));
// or map threshold as Integer with an INT column
Defensive patterns

Strategy: validation

Validate before calling

int i = Math.round(adcFloat);
if (i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) throw new IllegalArgumentException("ADC out of byte range: " + i);
pin.setThreshold((byte) i);

Type guard

static boolean fitsInByte(Float f) { return f != null && f == Math.rint(f) && f >= -128f && f <= 127f; }

Try / catch

try { session.persist(pin); } catch (CoercionException e) { throw new IllegalArgumentException("threshold not representable as byte", e); }

Prevention

When it happens

Trigger: Assigning a whole Float > 127 (e.g. 200.0f, 1e3f) to a Byte/byte entity field or binding it against a Byte-typed query parameter; e.g. `device.setPowerLevel(measuredFloat)` with powerLevel mapped from TINYINT.

Common situations: Sensor readings in float form feeding tinyint-mapped Byte fields; ADC values (0..1023.0f) stored into a byte column by mistake; ports/page sizes computed as Float; Hibernate 5 -> 6 migration surfacing previously truncated values.

Related errors


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