If you enable {{hibernate.query.in_clause_parameter_padding}} in {{persistence.xml}}and then execute the following query with 1900 parameters:
{{select m from MyEntity m where m.id in ?1}}
You will get this error {{ORA-01795: maximum number of expressions in a list is 1000}}.
The issue lies in {{AbstractSqlAstTranslator}}: if there are more {{listExpressions}} than {{inExprLimit}} and {{inClauseParameterPaddingEnabled}} is true then {{bindValueMaxCount}} is calculated as {{ceilingPowerOfTwo( bindValueCount % inExprLimit )}}. In our example this is {{ceilingPowerOfTwo(1900 % 1000) == 1024}}.
This result is then used to pad the last in clause without checking {{inExprLimit}} again:
[https://github.com/hibernate/hibernate-orm/blob/6746c30275b6600622d82613dc70b1fbf97a2fdf/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java#L6884-L6891|https://github.com/hibernate/hibernate-orm/blob/6746c30275b6600622d82613dc70b1fbf97a2fdf/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java#L6884-L6891|smart-link]
{code:java} if ( inClauseParameterPaddingEnabled ) { final Expression lastExpression = itemAccessor.apply( listExpressions.get( listExpressions.size() - 1 ) ); for ( ; ` itemNumber < bindValueMaxCount ; itemNumber++ ) { appendSql( separator ); lastExpression.accept( this ); separator = COMA_SEPARATOR; } }{code}
A simple fix would be to change the condition of this for-loop to {{itemNumber < Math.min(bindValueMaxCount, inExprLimit)}}, but I feel like the whole calculation could be simplified.
I added a testcase that reproduces the issue, but I don’t know how to write an assertion that would fail the test when there is an in clause with more than 1000 parameters. So the test always passes, but you can see the incorrectly generated SQL in the log: [https://github.com/Adrodoc/HHH-16589/commit/581cf4077622ce448b482859eb9097c2ec1c10cb|https://github.com/Adrodoc/HHH-16589/commit/581cf4077622ce448b482859eb9097c2ec1c10cb|smart-link] |
|