{"record":{"id":"754bd5ad9b3f35cd","repo":"hibernate/hibernate-orm","slug":"unable-to-coerce-value-s-s-to-biginteger","errorCode":null,"errorMessage":"Unable to coerce value [%s (%s)] to BigInteger","messagePattern":"Unable to coerce value \\[(.+?) \\((.+?)\\)\\] to BigInteger","errorType":"exception","errorClass":"CoercionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java","lineNumber":143,"sourceCode":"\n\t@Override\n\tpublic int getDefaultSqlPrecision(Dialect dialect, JdbcType jdbcType) {\n\t\treturn dialect.getDefaultDecimalPrecision();\n\t}\n\n\t@Override\n\tpublic int getDefaultSqlScale(Dialect dialect, JdbcType jdbcType) {\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic @Nullable BigInteger coerce(@Nullable Object value) {\n\t\tif ( value == null ) {\n\t\t\treturn null;\n\t\t}\n\t\tfinal var coerced = coerceOrNull( value );\n\t\tif ( coerced == null ) {\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 value [%s (%s)] to BigInteger\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\tvalue.getClass().getName()\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\treturn coerced;\n\t}\n\n\t@Override\n\tpublic @Nullable BigInteger coerceOrNull(@Nonnull Object value) {\n\t\tif ( value instanceof BigInteger bigInteger ) {\n\t\t\treturn bigInteger;\n\t\t}\n\n\t\tif ( value instanceof Byte byteValue ) {","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java#L125-L161","documentation":"BigIntegerJavaType.coerce applies Hibernate's implicit coercion toward java.math.BigInteger for mismatched values. coerceOrNull accepts BigInteger, any Number and parseable Strings; every other type, or a String that cannot be parsed as a double, results in this CoercionException naming the offending value and its class.","triggerScenarios":"Binding or assigning a value to a BigInteger attribute/parameter that is neither Number nor String (Boolean, enum, date), or a locale/formatted string like '1.000' (grouping) or '12ab' that Double.parseDouble rejects.","commonSituations":"IDs read from requests as formatted strings; grouping separators from European locales; passing a char[] or StringBuilder; converting DTO fields with mismatched types in mapper code; upgrade to Hibernate 6 where coercion replaced silent legacy behavior.","solutions":["Parse to BigInteger before binding, using the value's real locale and stripping grouping separators","Pass Number instances (long/Long is safest for IDs) instead of formatted text","Validate/normalize incoming strings at the API boundary (regex or NumberFormat.parse)","Check the value's class named in the message to find the offending caller"],"exampleFix":"// before\nquery.setParameter(\"userId\", \"1.000.000\"); // grouping separators -> CoercionException\n// after\nString digits = \"1.000.000\".replaceAll(\"[^0-9]\", \"\");\nquery.setParameter(\"userId\", new BigInteger(digits));","handlingStrategy":"type-guard","validationCode":"static BigInteger toBigInteger(Object v) {\n    if (v instanceof BigInteger bi) return bi;\n    if (v instanceof Number n) return BigInteger.valueOf(n.longValue());\n    if (v instanceof String s) return new BigInteger(s.replaceAll(\"[^\\\\d-]\", \"\"));\n    throw new IllegalArgumentException(\"Not coercible to BigInteger: \" + v);\n}","typeGuard":"static boolean isCoercibleToBigInteger(Object v) {\n    return v == null || v instanceof Number\n        || (v instanceof String s && s.matches(\"[+-]?\\\\d+\"));\n}","tryCatchPattern":"try {\n    query.setParameter(\"userId\", idValue);\n} catch (CoercionException e) {\n    if (idValue instanceof String s && s.matches(\"\\\\d+\")) {\n        query.setParameter(\"userId\", new BigInteger(s)); // digits only: retry clean\n    } else throw e;\n}","preventionTips":["Model IDs as long/Long or BigInteger end-to-end, not formatted strings","Reject grouping separators and whitespace in numeric input validation","Pass numbers, not their textual renderings, through service layers","Log the offending value/class named in the message to locate the caller"],"tags":["hibernate","orm","type-coercion","biginteger","query-parameters","number-format"],"backgroundTag":"number-coercion-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}