hibernate/hibernate-orm · error · CoercionException

Cannot coerce Integer value `%s` as Short : underflow

Error message

Cannot coerce Integer value `%s` as Short : underflow

What it means

Hibernate throws this CoercionException when an Integer is narrowed to Short and falls below -32768. It is thrown by CoercionHelper.toShort(Integer), reached through ShortJavaType.coerce during persist/merge or parameter binding on a Short-mapped attribute. It is the underflow counterpart of the overflow check in the same method, and exists because Hibernate 6 rejects lossy narrowing of numeric types.

Source

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

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

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

	public static Short toShort(Byte value) {
		return value.shortValue();
	}

	public static Short toShort(Integer value) {
		if ( value > Short.MAX_VALUE ) {
			throw new CoercionException( "Cannot coerce Integer value `" + value + "` as Short : overflow" );
		}

		if ( value < Short.MIN_VALUE ) {
			throw new CoercionException( "Cannot coerce Integer value `" + value + "` as Short : underflow" );
		}

		return value.shortValue();
	}

	public static Short toShort(Long value) {
		if ( value > Short.MAX_VALUE ) {
			throw new CoercionException( "Cannot coerce Long value `" + value + "` as Short : overflow" );
		}

		if ( value < Short.MIN_VALUE ) {
			throw new CoercionException( "Cannot coerce Long value `" + value + "` as Short : underflow" );
		}

		return value.shortValue();
	}

	public static Short toShort(Double doubleValue) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Re-type the attribute (Short -> Integer) and column (SMALLINT -> INT) if the domain needs values below -32768.
  2. Validate and narrow explicitly: range-check then `(short) value`.
  3. Eliminate out-of-range sentinel constants; use a properly sized column for special codes.
  4. Add boundary validation for any Number destined for Short fields before Session calls.

Example fix

// before
int signedOffset = computeSignedOffset();  // e.g. -70000
region.setOffset(signedOffset);            // Short 'offset' -> underflow

// after
if (signedOffset >= Short.MIN_VALUE && signedOffset <= Short.MAX_VALUE) {
    region.setOffset((short) signedOffset);
} else {
    throw new IllegalArgumentException("offset out of short range: " + signedOffset);
}
Defensive patterns

Strategy: validation

Validate before calling

if (intValue < Short.MIN_VALUE || intValue > Short.MAX_VALUE) {
    throw new IllegalArgumentException("offset out of short range: " + intValue);
}
region.setOffset((short) intValue);

Type guard

static boolean fitsInShort(int v) { return v >= -32768 && v <= 32767; }

Try / catch

catch CoercionException and map to a 422 validation response; deterministic, no retry value.

Prevention

When it happens

Trigger: Assigning an Integer < -32768 (e.g. -40000) to a Short/short entity field through a loosely typed setter, merging entities whose Short property was populated from an Integer variable, or binding a negative int literal below -32768 to a Short-typed query parameter.

Common situations: Negative sentinels (-99999) used as status codes stored in SMALLINT fields; coordinate/offset math in int overflowing the short domain; int-typed constants from other libraries pushed into Short attributes; Hibernate 5 -> 6 upgrades exposing formerly silent truncation.

Related errors


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