hibernate/hibernate-orm · error · CoercionException

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

Error message

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

What it means

DoubleJavaType.coerce(Object) is Hibernate's last-chance conversion of an arbitrary value to Double for double-typed attributes and query parameters: it delegates to coerceOrNull and throws CoercionException('Cannot coerce value ... to Double'), naming the offending value and its class, when no coercion rule matched and coerceOrNull returned null.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoubleJavaType.java:175

	@Override
	public int getDefaultSqlPrecision(Dialect dialect, JdbcType jdbcType) {
		return jdbcType.isFloat()
				// this is usually the number of *binary* digits
				// in a double-precision FP number
				? dialect.getDoublePrecision()
				// this is the number of decimal digits in a Java double
				: 17;
	}

	@Override
	public @Nullable Double 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 Double",
							value,
							value.getClass().getName()
					)
			);
		}
		return coerced;
	}

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

		if ( value instanceof Float floatValue ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Convert the value to Double yourself before binding: Double.parseDouble on a normalized string, or ((Number) v).doubleValue()
  2. Fix the producer: parse with the correct Locale, trim blanks, normalize decimal separators
  3. Type the parameter explicitly with setParameter(name, value, type) so coercion is not guessed
  4. Catch CoercionException at the API boundary and return a validation error

Example fix

// before
q.setParameter("rate", map.get("rate")); // value is String "3,5" -> CoercionException

// after
q.setParameter("rate", Double.parseDouble(map.get("rate").toString().replace(',', '.')));
Defensive patterns

Strategy: type-guard

Validate before calling

static Double toDoubleOrNull(Object v) {
    try {
        return v instanceof Number n ? n.doubleValue()
                : Double.parseDouble(String.valueOf(v).trim());
    } catch (RuntimeException e) {
        return null;
    }
}

Type guard

static boolean coercibleToDouble(Object v) {
    if (v == null || v instanceof Number || v instanceof Boolean) return true;
    return v instanceof String s && s.trim().matches("[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?");
}

Try / catch

try {
    return q.setParameter("rate", value).getSingleResult();
} catch (CoercionException e) {
    throw new BadRequestException("rate must be numeric", e);
}

Prevention

When it happens

Trigger: Binding a query parameter or setting a double-typed attribute with a value Hibernate cannot convert: a non-numeric or locale-formatted String ('abc', '', '1,5'), or an arbitrary object type (java.util.Date, a POJO, char[]) that the numeric coercion helper does not know.

Common situations: HQL/native setParameter with user input parsed as the wrong type; JSON deserialization straight onto entities; consuming Map<String,Object> rows; locale-formatted numbers from European formats.

Related errors


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