hibernate/hibernate-orm · error · CoercionException

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

Error message

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

What it means

Hibernate throws this CoercionException when a whole-number Float is narrowed to Byte below -128. CoercionHelper.toByte(Float) checks isWholeNumber, then the upper bound, then fails `value < Byte.MIN_VALUE`. It is reached through ByteJavaType.coerce when a Float value is coerced for a Byte-mapped attribute. Like its siblings it is a fail-fast rejection of lossy narrowing, with the bad value included in the message.

Source

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

							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
					)
			);
		}

		return value.byteValue();
	}

	public static Byte toByte(BigInteger value) {
		return coerceWrappingError( value::byteValueExact );
	}

	public static Byte toByte(BigDecimal value) {
		return coerceWrappingError( value::byteValueExact );
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Re-type the attribute/column to fit the value domain (Float/Integer instead of Byte).
  2. Guard and narrow explicitly: round, verify -128..127, then cast to byte.
  3. Fix the upstream computation producing out-of-range magnitudes (sign/unit errors).
  4. Reject out-of-range inputs at the service boundary with domain-specific errors.

Example fix

// before
Float correction = baseline - sample;   // e.g. -400.0f
station.setCorrection(correction);      // Byte field -> underflow

// after
int i = Math.round(correction);
if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
    station.setCorrection((byte) i);
} else {
    throw new IllegalArgumentException("correction out of range: " + i);
}
Defensive patterns

Strategy: validation

Validate before calling

int i = Math.round(correction);
if (i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) throw new IllegalArgumentException("correction out of range: " + i);
station.setCorrection((byte) i);

Type guard

static boolean fitsInByteFloat(Float f) { return f != null && f == Math.rint(f) && f >= Byte.MIN_VALUE && f <= Byte.MAX_VALUE; }

Try / catch

catch CoercionException; convert to domain error; log the numeric value for diagnosis.

Prevention

When it happens

Trigger: Assigning whole Floats < -128 (e.g. -255.0f) to Byte/byte attributes: `station.setCorrection(-255.0f)`, or binding such a value as a query parameter on a Byte path.

Common situations: Negative calibration offsets or temperature-like floats stored in tinyint Byte fields; overflow of magnitude in float pipelines (subtracting baselines); legacy Float-typed service interfaces feeding Byte entities; silent-truncation-to-strict upgrade from Hibernate 5.

Related errors


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