{"record":{"id":"0b600a1553365478","repo":"hibernate/hibernate-orm","slug":"ordinal-parameter-label-was-not-an-integer","errorCode":null,"errorMessage":"Ordinal parameter label was not an integer","messagePattern":"Ordinal parameter label was not an integer","errorType":"exception","errorClass":"ParameterLabelException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java","lineNumber":189,"sourceCode":"\t\t\t\t\t\t\t\trecognizer.other( ':' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( c == '?' ) {\n\t\t\t\t\t// could be either a positional or JPA-style ordinal parameter\n\t\t\t\t\tif ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) {\n\t\t\t\t\t\t// a peek ahead showed this as a JPA-positional parameter\n\t\t\t\t\t\tfinal int right = StringHelper.firstIndexOfChar( sqlString, HQL_SEPARATORS, indx + 1 );\n\t\t\t\t\t\tfinal int chopLocation = right < 0 ? sqlString.length() : right;\n\t\t\t\t\t\tfinal String param = sqlString.substring( indx + 1, chopLocation );\n\t\t\t\t\t\t// make sure this \"name\" is an integral\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\trecognizer.jpaPositionalParameter( Integer.parseInt( param ), indx );\n\t\t\t\t\t\t\tindx = chopLocation - 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch( NumberFormatException e ) {\n\t\t\t\t\t\t\tthrow new ParameterLabelException( \"Ordinal parameter label was not an integer\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif ( !nativeJdbcParametersIgnored ) {\n\t\t\t\t\t\t\trecognizer.ordinalParameter( indx );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\trecognizer.other( c );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trecognizer.complete();\n\t}\n\n\tpublic static void parse(String sqlString, ParameterRecognizer recognizer) throws QueryException {","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java#L171-L207","documentation":"When ParameterParser sees '?' followed by a digit it assumes a JPA-style ordinal parameter and must parse everything up to the next separator as an integer. If that token contains non-digits (e.g. '?1a', '?2b'), Integer.parseInt throws NumberFormatException and Hibernate rethrows it as ParameterLabelException with this message.","triggerScenarios":"A native or HQL query string containing a token like '?1x', '?01a', or '?2foo' — i.e. '?' + digits + trailing letters/underscore, since letters are not separators and become part of the chopped token. Triggered at query creation when the string is parsed, before any parameter binding.","commonSituations":"Typos when relabeling JDBC '?' parameters to JPA '?n' style; SQL dialect text or JSON path expressions colliding with '?digit+letter' sequences; copy-pasted snippets mixing named and ordinal styles.","solutions":["Make the label a pure integer: use ?1, ?2, ... with no trailing characters.","If the trailing text was accidental (e.g. '?1a' meant '?1 AND a'), add the missing separator (space, comma, parenthesis) after the label.","If the '?...' sequence is literal SQL for your dialect, wrap it in quotes or restructure the SQL so it is not parsed as a parameter.","Prefer named parameters (:name) in native queries to avoid ordinal parsing entirely."],"exampleFix":"-- before\nselect * from person where id = ?1a and name = :name\n\n-- after\nselect * from person where id = ?1 and name = :name","handlingStrategy":"validation","validationCode":"static void validateOrdinalLabelsAreIntegers(String sql) {\n    var m = java.util.regex.Pattern.compile(\"\\\\?(\\\\d+[A-Za-z_\\\\w]*)\").matcher(sql);\n    if (m.find()) throw new IllegalArgumentException(\"Bad ordinal parameter label '\" + m.group(1) + \"' — labels must be pure integers like ?1\");\n}","typeGuard":null,"tryCatchPattern":"try { em.createNativeQuery(sql); } catch (org.hibernate.query.ParameterLabelException e) { /* locate '?<digits><letters>' in sql and fix */ throw e; }","preventionTips":["Use only ?1, ?2, ... labels — never append letters.","Run the regex check in a unit test over your SQL resources.","Prefer named parameters in native queries."],"tags":["hibernate","positional-parameter","ordinal-parameter","parameter-label-exception","native-query"],"backgroundTag":"jpa-ordinal-parameter-label-invalid","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}