Nullpointer wenn using setFirstResult and setMaxResults in diffrent combinations
Description
Attachments
- 10 Aug 2023, 08:48 AM
- 10 Aug 2023, 08:48 AM
Activity
Jan Schatteman August 15, 2023 at 12:36 PM
@Leopold Odenthal It took some divine (@Christian Beikov ) intervention to be able to simulate the failure, but once that was possible the solution was easy. Btw your suspición was absolutely right, thanks for your assistance in this.
Jan Schatteman August 10, 2023 at 8:53 PM
I’m scratching my head on this one; I’m still unable to reproduce the issue. That said, I must admit that I don’t have access to a Cache DB, so i tried first with the SybaseASEDialect (which also uses the TLH), and also tried to ‘fake’ it by configuring the TopLimitHandler to the H2Dialect, and tried it in 6.2.5, but still to no avail. So either the TopLimitHandler is not the culprit in this story, or there is something else that I’m missing in the picture.
Also, during debugging I saw that it never goes into that if you mentioned, are you sure this is the snippet you wanted to refer to?
if ( localCopy.jdbcSelect.dependsOnParameterBindings() ) {
jdbcParameterBindings = createJdbcParameterBindings( localCopy, executionContext );
}
Leopold Odenthal August 10, 2023 at 8:46 AMEdited
This issue is also related to the dialect and LimitHandler being used.
We are using org.hibernate.community.dialect.CacheDialect that using a TopLimitHandler.
Depending on whether the code enters the if condition in org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan#withCacheableSqmInterpretation
else {
// If the translation depends on parameter bindings or it isn't compatible with the current query options,
// we have to rebuild the JdbcSelect, which is still better than having to translate from SQM to SQL AST again
if ( localCopy.jdbcSelect.dependsOnParameterBindings() ) {
jdbcParameterBindings = createJdbcParameterBindings( localCopy, executionContext );
}
I've added a test that reproduces the issue. With H2, for instance, it works since a different limit handler is used, and the code that triggers the error isn't executed.
Jan Schatteman August 1, 2023 at 6:13 PM
Adding to my first comment, I would advise you to try in ‘pure’ Hibernate, i.e. without the Spring layer in between.
Jan Schatteman July 28, 2023 at 6:49 PM
I have to say, I added your test (see the PR), but i couldn’t reproduce the issue in main, nor in 6.2.5, everything seems to work correctly (at least that NPE doesn’t happen). Is there perhaps something missing in the test above (e.g. in the way how the entitymanager is obtained, … ) ?
When using EntityManager Query
setFirstResult
andsetMaxResults
and exuxute the same query again, but just withsetMaxResults
it results in a NullPointer.The problem is in the caching of the parameters when a same query is executed. There is a parameter validation here that look wrong:
JdbcOperationQuerySelect
.isCompatible
Current:
return value != (int) jdbcParameterBinding.getBindValue();
But should be:
return value == (int) jdbcParameterBinding.getBindValue();
@Test public void testMaxAndLimit_HQL_BUG() { EntityManager entityManager = Services.getEntityManager(); TypedQuery<MitarbeiterEntity> query = entityManager.createQuery("select m from MitarbeiterEntity m", MitarbeiterEntity.class); query.setMaxResults(10); query.getResultList(); query = entityManager.createQuery("select m from MitarbeiterEntity m", MitarbeiterEntity.class); query.setMaxResults(10); query.setFirstResult(2); query.getResultList(); query = entityManager.createQuery("select m from MitarbeiterEntity m", MitarbeiterEntity.class); query.setMaxResults(10); query.getResultList(); }