hibernate/hibernate-orm · error · CoercionException

Cannot coerce value '%s' [%s] to Short

Error message

Cannot coerce value '%s' [%s] to Short

What it means

ShortJavaType.coerce() runs when Hibernate must convert a bound or read value into a Short (parameter binding, result coercion). It calls coerceOrNull (numeric widening/narrowing, numeric strings) and throws CoercionException naming the value and its class when no conversion exists. The value's runtime type is fundamentally unconvertible to Short - it is not merely an overflow problem.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortJavaType.java:154

	@Override
	public int getDefaultSqlPrecision(Dialect dialect, JdbcType jdbcType) {
		return 5;
	}

	@Override
	public int getDefaultSqlScale(Dialect dialect, JdbcType jdbcType) {
		return 0;
	}

	@Override
	public @Nullable Short coerce(@Nullable Object value) {
		if ( value == null ) {
			return null;
		}
		final var coerced = coerceOrNull( value );
		if ( coerced == null ) {
			throw new CoercionException(
					String.format(
							Locale.ROOT,
							"Cannot coerce value '%s' [%s] to Short",
							value,
							value.getClass().getName()
					)
			);
		}
		return coerced;
	}

	@Override
	public @Nullable Short coerceOrNull(@Nonnull Object value) {
		if ( value instanceof Short shortValue ) {
			return shortValue;
		}

		if ( value instanceof Byte byteValue ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Pass a numeric value or numeric string; convert explicitly with ((Number) v).shortValue() before binding
  2. For native queries, CAST the selected expression in SQL or remap the attribute to the actual column type
  3. Bind with an explicit TypedParameterValue to avoid implicit coercion of the wrong runtime type
  4. Validate inputs before binding (e.g. Number instance check or \d+ regex for strings)

Example fix

// before
query.setParameter("code", codeDto); // CoercionException: Cannot coerce value '...' to Short

// after
query.setParameter("code", codeDto.getCode().shortValue());
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean coercibleToShort(Object v) {
    if (v == null || v instanceof Number) return true;
    if (v instanceof String s) return s.matches("[+-]?\d+");
    return false;
}

if (!coercibleToShort(param)) throw new IllegalArgumentException("Not coercible to Short: " + param);

Type guard

static Short toShortOrNull(Object v) {
    if (v instanceof Number n) { long l = n.longValue(); return (l >= Short.MIN_VALUE && l <= Short.MAX_VALUE) ? (short) l : null; }
    if (v instanceof String s && s.matches("[+-]?\d+")) return Short.valueOf(s);
    return null;
}

Try / catch

try { Short bound = ShortJavaType.INSTANCE.coerce(value); }
catch (CoercionException e) {
    throw new IllegalArgumentException("Parameter is not numeric: cannot bind to Short", e);
}

Prevention

When it happens

Trigger: query.setParameter("n", someObject) where the parameter implies Short but the argument is an enum, date, or arbitrary object; native query results mapped to Short attributes returning non-numeric column types; criteria expressions or DB function results coerced to Short

Common situations: Refactors that changed a DTO field type while callers still pass the old object; native queries against views where the column type changed; non-numeric strings bound to Short parameters

Related errors


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