{"record":{"id":"a32350f2275b0101","repo":"hibernate/hibernate-orm","slug":"unable-to-coerce-float-value-s-to-integer-not","errorCode":null,"errorMessage":"Unable to coerce Float value `%s` to Integer: not a whole number","messagePattern":"Unable to coerce Float value `(.+?)` to 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":248,"sourceCode":"\t}\n\n\tpublic static Integer toInteger(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` to 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\n\t\treturn toInteger( doubleValue.longValue() );\n\t}\n\n\tpublic static Integer toInteger(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` to 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\n\t\treturn toInteger( floatValue.longValue() );\n\t}\n\n\tpublic static Integer toInteger(BigInteger value) {\n\t\treturn coerceWrappingError( value::intValueExact );\n\t}\n\n\tpublic static Integer toInteger(BigDecimal value) {\n\t\treturn coerceWrappingError( value::intValueExact );\n\t}","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CoercionHelper.java#L230-L266","documentation":"Hibernate throws this CoercionException when a Float with a fractional part is coerced to Integer. CoercionHelper.toInteger(Float) first checks isWholeNumber(floatValue); values like 3.14f fail before any narrowing occurs. It is invoked from IntegerJavaType.coerce when a Float value is assigned to or bound against an Integer-mapped attribute. Hibernate deliberately blocks lossy fractional-to-integral coercion rather than silently truncating.","triggerScenarios":"`IntegerJavaType.coerce(3.14f)` — e.g. `entity.setQuantity(floatComputedValue)` on an int/Integer attribute, or `setParameter(\"qty\", 2.9f)` against an Integer-typed path; typical with UI components or math APIs returning Float for counts.","commonSituations":"Slider/progress Float values from UI toolkits persisted into INTEGER columns; float-based math feeding quantity/count fields; legacy Float-typed interfaces; NoSQL or analytics sources yielding floats for integral data.","solutions":["Round deliberately when truncation is fine: `Math.round(f)` then int assignment; otherwise store as FLOAT/DOUBLE.","Fix producers to emit integral types for count-like fields.","Validate incoming Numbers are whole before mapping onto Integer attributes.","Where a fixed policy exists, centralize it in an AttributeConverter<Float,Integer>."],"exampleFix":"// before\nFloat progress = reportEngine.completion();  // e.g. 66.6f\nreport.setProgress(progress);                 // Integer 'progress' -> \"not a whole number\"\n\n// after\nreport.setProgress(Math.round(progress));\n// or declare progress as Float with a FLOAT column","handlingStrategy":"validation","validationCode":"Float f = engine.completion();\nif (f != Math.rint(f)) throw new IllegalArgumentException(\"progress must be whole: \" + f);\nreport.setProgress(Math.round(f));","typeGuard":"static boolean isWholeFloat(Float f) { return f != null && !f.isNaN() && !f.isInfinite() && f == Math.rint(f); }","tryCatchPattern":"catch CoercionException and translate to a validation error naming the field; deterministic — no retry.","preventionTips":["Convert float progress/ratio outputs to int at the producing layer.","Map genuinely fractional metrics to FLOAT/DOUBLE columns.","Reject NaN/Infinity floats early in numeric pipelines."],"tags":["hibernate","type-coercion","integer","float","fractional"],"backgroundTag":"fractional-to-integer-coercion","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}