{"record":{"id":"175792b7fee02f21","repo":"hibernate/hibernate-orm","slug":"cannot-coerce-float-value-s-to-double-underfl","errorCode":null,"errorMessage":"Cannot coerce Float value `%s` to Double : underflow","messagePattern":"Cannot coerce Float value `(.+?)` to Double : underflow","errorType":"exception","errorClass":"CoercionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java","lineNumber":356,"sourceCode":"\t}\n\n\tpublic static BigInteger toBigInteger(BigDecimal value) {\n\t\treturn coerceWrappingError( value::toBigIntegerExact );\n\t}\n\n\tpublic static Double toDouble(Float floatValue) {\n\t\tif ( floatValue > (float) Double.MAX_VALUE ) {\n\t\t\tthrow new CoercionException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Cannot coerce Float value `%s` to Double : overflow\",\n\t\t\t\t\t\t\tfloatValue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( floatValue < (float) Double.MIN_VALUE ) {\n\t\t\tthrow new CoercionException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Cannot coerce Float value `%s` to Double : underflow\",\n\t\t\t\t\t\t\tfloatValue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\treturn (double) floatValue;\n\t}\n\n\tpublic static Double toDouble(BigInteger value) {\n\t\treturn coerceWrappingError( value::doubleValue );\n\t}\n\n\tpublic static Double toDouble(BigDecimal value) {\n\t\treturn coerceWrappingError( value::doubleValue );\n\t}","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L338-L374","documentation":"Thrown by CoercionHelper.toDouble(Float) when floatValue < (float) Double.MIN_VALUE. Double.MIN_VALUE is the smallest positive double (~4.9e-324) and casting it to float yields 0.0f, so the condition degenerates to 'floatValue < 0.0f': in this Hibernate version every negative Float fails Float-to-Double widening with 'underflow', even though all negative floats fit comfortably in a double. This is a bug in the guard, not a genuine range problem with your data.","triggerScenarios":"Binding any negative Float where a double is expected: query.setParameter(\"delta\", -1.5f) on a Double-typed attribute or path; an AttributeConverter or HQL coercion path that feeds a boxed Float into CoercionHelper.toDouble(Float).","commonSituations":"Entity fields typed Double receiving float literals (the f suffix) or Float values from older APIs; codebases mixing float and double after a schema or entity refactor; failures that appear after upgrading to Hibernate 6.x coercion-based binding.","solutions":["Widen the value yourself before Hibernate sees it: pass Double.valueOf(f) or (double) f instead of the Float","Change float fields, variables, and parameters to double so the Float overload is never exercised","Upgrade hibernate-core to a release where the negative-float underflow check is corrected","Interim workaround: catch CoercionException and re-coerce from the original value"],"exampleFix":"// before\nquery.setParameter(\"amount\", -1.5f); // Float -> CoercionException: underflow\n\n// after\nquery.setParameter(\"amount\", -1.5); // double literal, Float coercion path avoided","handlingStrategy":"type-guard","validationCode":"// pre-widen every Float before Hibernate sees it\nstatic Object widenFloats(Object v) {\n    return v instanceof Float f ? f.doubleValue() : v;\n}","typeGuard":"static boolean safeForDoubleCoercion(Object v) {\n    // on affected versions every negative Float trips the underflow guard\n    return !(v instanceof Float f) || !(f < 0f);\n}","tryCatchPattern":"try {\n    return query.getSingleResult();\n} catch (CoercionException e) {\n    if (e.getMessage().contains(\"underflow\") && original instanceof Float f) {\n        return rebind(f.doubleValue()); // widen and retry once\n    }\n    throw e;\n}","preventionTips":["Standardize on double (not float) for entity fields and query parameters","Grep the codebase for f-suffix literals passed into setParameter","Track the Hibernate release notes and upgrade once the underflow fix ships"],"tags":["hibernate","type-coercion","numeric","float","underflow","regression"],"backgroundTag":"numeric-type-coercion-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}