{"record":{"id":"2e96c226a0c550ef","repo":"hibernate/hibernate-orm","slug":"null-value-not-allowed-for-multi-valued-parameter-2e96c2","errorCode":null,"errorMessage":"Null value not allowed for multi-valued parameter '?{position}'","messagePattern":"Null value not allowed for multi-valued parameter '\\?(.+?)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java","lineNumber":1128,"sourceCode":"\t\t\t@Nonnull String name,\n\t\t\t@Nullable Instant value,\n\t\t\t@Nonnull TemporalType temporalType) {\n\t\tlocateBinding( name ).setBindValue( value, temporalType );\n\t\treturn this;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic CommonQueryContractImplementor setParameter(int position, @Nullable Object value) {\n\t\tsession.checkOpen( false );\n\t\tif ( value instanceof TypedParameterValue<?> typedParameterValue ) {\n\t\t\tsetTypedParameter( position, typedParameterValue );\n\t\t}\n\t\telse {\n\t\t\tfinal var binding = getQueryParameterBindings().getBinding( position );\n\t\t\tif ( multipleBinding( binding.getQueryParameter(), value ) ) {\n\t\t\t\tif ( value == null ) {\n\t\t\t\t\tthrow new IllegalArgumentException( \"Null value not allowed for multi-valued parameter '?\" + position + \"'\" );\n\t\t\t\t}\n\t\t\t\tsetParameterList( position, (Collection<?>) value );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbinding.setBindValue( value, resolveJdbcParameterTypeIfNecessary() );\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic CommonQueryContractImplementor setParameters(@Nonnull Object... arguments) {\n\t\tfinal int parameterCount = getParameterMetadata().getOrdinalParameterLabels().size();\n\t\tif ( arguments.length != parameterCount ) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Received \" + arguments.length + \" arguments for \"\n\t\t\t\t\t\t\t+ parameterCount + \" positional parameters\"","sourceCodeStart":1110,"sourceCodeEnd":1146,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java#L1110-L1146","documentation":"Positional twin of error 2374: in setParameter(int position, Object value), when the ordinal parameter allows multi-valued binding and multipleBinding(...) is true, a null value is rejected with IllegalArgumentException ('?position' formatted into the message) instead of being cast to Collection for setParameterList. As with the named variant, the current multipleBinding() implementation returns false for null (it requires value instanceof Collection), so this throw is a defensive guard for the rule 'multi-valued parameters may not be null' rather than the live path.","triggerScenarios":"The guarded scenario: query.setParameter(1, null) where ?1 participates in an IN expansion ('?1 in'-style or collection-typed parameter). Helper layers that forward varargs positions with possible nulls, e.g. setParameter(i+1, args[i]) with null elements for missing optional values.","commonSituations":"Dynamic filters using positional parameters with optional collections; vararg-driven binders receiving sparse arrays; refactors from named to positional parameters keeping null-when-absent logic.","solutions":["Pass an empty collection (List.of()) instead of null for collection-typed positional parameters","Use setParameterList(position, values) explicitly so intent is unambiguous","Omit the IN predicate dynamically when the collection is absent rather than binding null"],"exampleFix":"// before\nquery.setParameter( 1, idsOrNull ); // null into multi-valued ?1\n\n// after\nquery.setParameterList( 1, idsOrNull == null ? List.of() : idsOrNull );","handlingStrategy":"validation","validationCode":"if ( value instanceof Collection<?> c ) {\n    query.setParameterList( position, c );\n} else if ( value == null && query.getParameterMetadata()\n            .getQueryParameter( position ).allowsMultiValuedBinding() ) {\n    query.setParameterList( position, List.of() );\n} else {\n    query.setParameter( position, value );\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize null→empty list at the API boundary before any positional bind","Prefer setParameterList for collection-typed positional parameters","For sparse optional args, bind defaults for every position up-front"],"tags":["hibernate","query-parameters","null-safety","in-clause","positional-parameters"],"backgroundTag":"null-parameter-value","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}