{"record":{"id":"72b2ef31f4f66939","repo":"hibernate/hibernate-orm","slug":"unable-to-coerce-double-float-s-as-biginteger","errorCode":null,"errorMessage":"Unable to coerce Double Float `%s` as BigInteger: not a whole number","messagePattern":"Unable to coerce Double Float `(.+?)` as BigInteger: not a whole number","errorType":"exception","errorClass":"CoercionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java","lineNumber":329,"sourceCode":"\t\treturn coerceWrappingError( value::longValueExact );\n\t}\n\n\tpublic static BigInteger toBigInteger(Double doubleValue) {\n\t\tif ( ! isWholeNumber( doubleValue ) ) {\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\"Unable to coerce Double value `%s` as BigInteger: not a whole number\",\n\t\t\t\t\t\t\tdoubleValue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\treturn BigInteger.valueOf( doubleValue.longValue() );\n\t}\n\n\tpublic static BigInteger toBigInteger(Float floatValue) {\n\t\tif ( ! isWholeNumber( floatValue ) ) {\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\"Unable to coerce Double Float `%s` as BigInteger: not a whole number\",\n\t\t\t\t\t\t\tfloatValue\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\treturn BigInteger.valueOf( floatValue.longValue() );\n\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(","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L311-L347","documentation":"Thrown by CoercionHelper.toBigInteger(Float) when Hibernate coerces a Float into a BigInteger basic type and the isWholeNumber(floatValue) check fails, i.e. the value has a fractional part. Hibernate runs this coercion when a BigInteger attribute or query parameter receives a float-typed value. The odd wording 'Double Float' is a copy-paste artifact from the Double overload; the real meaning is simply that the Float is not a whole number.","triggerScenarios":"Binding a fractional float such as setParameter(\"n\", 2.5f) where the path/attribute is BigInteger; assigning a Float that came from JSON, a Map<String,Object>, or a reflective setter to a BigInteger entity field; result coercion when the declared Java type is BigInteger but the incoming value arrives boxed as Float.","commonSituations":"Loosely typed input (JSON payloads, row maps) mapped onto strict numeric entity fields; refactoring a field from Double/Float to BigInteger without cleaning producers; older service APIs that hand out Float for quantities now stored as integers.","solutions":["Round or truncate explicitly before assigning: BigInteger.valueOf(floatValue.longValue()) or Math.round, so the lossy conversion is intentional","Change the entity attribute type to match the real data (BigDecimal or Double) instead of BigInteger","Pass the exact target type from the start and remove float-typed intermediaries","As a boundary guard, catch org.hibernate.type.descriptor.java.CoercionException and reject the input with a validation error"],"exampleFix":"// before\nentity.setAmount(2.5f); // field is BigInteger -> CoercionException: not a whole number\n\n// after\nentity.setAmount(BigInteger.valueOf((long) 2.5f)); // explicit truncation\n// or better: change the field to BigDecimal and keep the fraction","handlingStrategy":"validation","validationCode":"static BigInteger toBigIntegerSafe(Float v) {\n    if (v == null) return null;\n    if (!v.isFinite() || v % 1.0f != 0.0f) {\n        throw new IllegalArgumentException(\"not a whole number: \" + v);\n    }\n    return BigInteger.valueOf(v.longValue());\n}","typeGuard":"static boolean isWholeFloat(Number n) {\n    return n instanceof Float f && f.isFinite() && f % 1.0f == 0.0f;\n}","tryCatchPattern":"try {\n    session.persist(entity);\n} catch (CoercionException e) {\n    // rethrow as a user-facing validation error naming the field\n    throw new BadRequestException(\"value must be a whole number\", e);\n}","preventionTips":["Keep entity attribute types aligned with the values you actually set","Never rely on implicit Number coercion for BigInteger fields","Unit-test setters with the exact runtime types your JSON/deserializer produces"],"tags":["hibernate","type-coercion","numeric","biginteger","float"],"backgroundTag":"numeric-type-coercion-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}