hibernate/hibernate-orm · error · CoercionException

Error coercing value

Error message

Error coercing value

What it means

CoercionHelper.coerceWrappingError runs an 'exact' conversion (BigDecimal.toBigIntegerExact, exact narrowing ops, numeric string parsing) and rethrows any ArithmeticException or NumberFormatException as a CoercionException with the generic message 'Error coercing value', keeping the original exception as the cause. It exists so Hibernate surfaces one exception type across all coercions; the actual reason is always in getCause().

Source

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

	}

	public static CoercionException coercionException(Exception e) {
		var ce = new CoercionException( e.getMessage() );
		ce.addSuppressed( e );
		return ce;
	}

	@FunctionalInterface
	public interface Coercer<T> {
		T doCoercion();
	}

	public static <T> T coerceWrappingError(Coercer<T> coercer) {
		try {
			return coercer.doCoercion();
		}
		catch (ArithmeticException | NumberFormatException e) {
			throw new CoercionException( "Error coercing value", e );
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inspect e.getCause(): ArithmeticException means fractional or overflowing value, NumberFormatException means unparseable string
  2. Validate and normalize inputs before binding (setScale with an explicit RoundingMode, pre-parse strings)
  3. For BigDecimal sources, decide a policy: reject, or setScale(0, RoundingMode.HALF_UP) before converting
  4. Catch CoercionException at the API boundary and turn it into a user-facing validation message

Example fix

// before
BigInteger b = new BigDecimal("1.5").toBigIntegerExact(); // ArithmeticException, wrapped by Hibernate

// after
BigInteger b = new BigDecimal("1.5").setScale(0, RoundingMode.HALF_UP).toBigIntegerExact();
Defensive patterns

Strategy: try-catch

Validate before calling

static BigDecimal validated(String raw) {
    if (raw == null || !raw.matches("[+-]?[0-9]+(\\.[0-9]+)?")) {
        throw new IllegalArgumentException("not a number: " + raw);
    }
    return new BigDecimal(raw);
}

Try / catch

try {
    return CoercionHelper.toBigInteger(bigDecimalValue);
} catch (CoercionException e) {
    Throwable cause = e.getCause();
    // ArithmeticException -> fractional/overflow; NumberFormatException -> bad string
    throw new IllegalArgumentException("value not coercible: " + cause, e);
}

Prevention

When it happens

Trigger: toBigInteger on a fractional BigDecimal such as new BigDecimal("1.5") (toBigIntegerExact throws ArithmeticException 'Rounding necessary'); coercing an unparseable numeric string ('12abc', '') through the numeric helpers; exact BigInteger/BigDecimal narrowing where the value overflows the target type.

Common situations: External input arriving as strings or BigDecimals and bound to integer-typed attributes; CSV/ETL loads; converters that assumed input was already integral.

Related errors


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