{"record":{"id":"d4a919d9580c8fc3","repo":"hibernate/hibernate-orm","slug":"unable-to-coerce-float-value-s-as-integer-not","errorCode":null,"errorMessage":"Unable to coerce Float value `%s` as Integer: not a whole number","messagePattern":"Unable to coerce Float value `(.+?)` as Integer: 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":295,"sourceCode":"\t\treturn value.longValue();\n\t}\n\n\tpublic static Long toLong(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 Integer: 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 doubleValue.longValue();\n\t}\n\n\tpublic static Long toLong(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 Float value `%s` as Integer: 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 floatValue.longValue();\n\t}\n\n\tpublic static Long toLong(BigInteger value) {\n\t\treturn coerceWrappingError( value::longValueExact );\n\t}\n\n\tpublic static Long toLong(BigDecimal value) {\n\t\treturn coerceWrappingError( value::longValueExact );\n\t}\n","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L277-L313","documentation":"Hibernate throws this CoercionException when a Float with a fractional part is coerced to Long. As with its Double sibling, the message text is wrong: CoercionHelper.toLong(Float) says \"as Integer\" even though the target is Long — a copy-paste artifact in Hibernate, so trust the stack trace (LongJavaType.coerce -> toLong) over the message wording. The isWholeNumber guard fires from LongJavaType.coerce whenever a fractional Float reaches a Long-mapped attribute.","triggerScenarios":"`LongJavaType.coerce(2.5f)` — assigning a Float to a Long/long field (counts, durations, ids) through a Number/Object-typed setter or dynamic map, or `setParameter(\"n\", 3.7f)` bound against a Long-typed path.","commonSituations":"Float-valued durations or scores from UIs/simulations persisted into BIGINT-mapped Long fields; loosely typed Map<String,Object> payloads; developers misled by the \"Integer\" text in the message while actually debugging a Long mapping; analytics feeds emitting floats for integral counts.","solutions":["Fix the producer to emit integral types, or convert explicitly: verify whole-number then `floatValue()`/`Math.round(f)` before assigning to the Long field.","Store fractional values in FLOAT/DOUBLE columns rather than BIGINT.","Validate incoming Numbers for whole-number-ness at the boundary.","Read the stack trace, not the message: this variant is the Float -> Long case despite the Integer wording."],"exampleFix":"// before\nFloat elapsed = timer.elapsedFraction();  // e.g. 12.9f\njob.setDuration(elapsed);                 // Long 'duration' -> CoercionException (message says \"as Integer\")\n\n// after\njob.setDuration((long) Math.round(elapsed));\n// or map duration as Float if sub-second fractions matter","handlingStrategy":"validation","validationCode":"Float f = timer.fraction();\nif (f != Math.rint(f)) throw new IllegalArgumentException(\"duration must be whole: \" + f);\njob.setDuration((long) Math.round(f));","typeGuard":"static boolean isWholeFloatForLong(Float f) { return f != null && f == Math.rint(f) && !f.isNaN() && !f.isInfinite(); }","tryCatchPattern":"catch CoercionException; the message says \"as Integer\" but the target is Long — use the stack trace to classify; map to a validation error.","preventionTips":["Produce durations as long milliseconds, not float seconds.","Keep loosely typed Map payloads out of Long-mapped fields.","When this appears with \"Integer\" text, don't chase Integer mappings — check Long attributes."],"tags":["hibernate","type-coercion","long","float","fractional","misleading-message"],"backgroundTag":"fractional-to-integer-coercion","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}