-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Parameter cached as incorrect type for Boolean when null value is queried for first on field with AttributeConverter #3060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
|
@mp911de may not have been clear from the last sentence within the background—using the EntityManager directly behaves correctly from within the repo I shared (https://github.com/adrianhj/spring-data-jpa-3060/blob/main/src/test/java/com/example/jpa/JpaTests.java#L52), I am only seeing the issue when interacting through a Spring Data JPA repository. Would you still suggest this is more suited within the Hibernate project under those circumstances? |
The reproducer doesn't actually apply what Spring Data is doing. We use When I rewrite your reproducer to hand in BasicTypeRegistry typeHelper = em.getEntityManagerFactory() //
.unwrap(SessionFactoryImplementor.class) //
.getTypeConfiguration() //
.getBasicTypeRegistry();
BasicType<Boolean> registeredType = typeHelper.getRegisteredType(Boolean.class);
assertThatCode(() -> query.setParameter("enabled", new TypedParameterValue<>(registeredType, null)).getResultList()).doesNotThrowAnyException();
assertThatCode(() -> query.setParameter("enabled", true).getResultList()).doesNotThrowAnyException();
Yeah, I think that isn't a Spring Data bug. |
Thank you very much for the follow-up; I was just the stepping through I need to educate myself on the expectation around converters/behaviours in these scenarios. Talking to members from the Hibernate team yesterday it sounded like the the caching of the binding that seems to be occuring for the second invocation was potentially unexpected so going to follow-up on that front. |
Hi @adrianhj we have similar kind of problem. Is there another open bug on hibernate side or did you found out work around for this? |
Thanks for the update. Feel free to drop a link here to the Hibernate ticket if you have one. |
I ended up discussing the issue with Gavin on the Hibernate side based on what Spring Data JPA was doing around the null handling with The main view was that the behaviour was incorrect Spring Data JPA side in its interaction with Hibernate (as passing null directly into the EntityManager works OK). If I recall right from hunting around issue tracker here and Hibernate at the time the introduction of the behaviour was based on another issue seen with native queries and null handling where it was the recommended approach to ensure things were catered for properly when executing the query via those code paths. Disabling plan caching removes the issue as each invocation is reparsed, but didn't feel right. For the areas where we were affected we are dropping down to our own implementation and calling the EntityManager direct. |
That's an interesting spin, that Spring Data does things supposedly wrong but disabling a Hibernate caching feature fixes the problem. |
https://hibernate.zulipchat.com/#narrow/stream/132096-hibernate-user/topic/.E2.9C.94.20Parameter.20binding.20as.20incorrect.20type.20on.20null.20with.20Converter/near/374576975 is the context if it is of interest. As #2370 and its related Hibernate issues of https://hibernate.atlassian.net/browse/HHH-14411 and https://hibernate.atlassian.net/browse/HHH-14778 seem scoped to the native query path only, would constraining the mapping of null to a |
Thanks a lot for the background. With the additional details it makes sense to constrain |
Background
We are encountering the below issue as part of our upgrade from Spring Boot 2.7.13 to Spring Boot 3.1.1 whereby if we perform an initial query against a repository of an entity with a boolean -> Y/N converter using a null
Boolean
parameter for awhere :param is null or x.field = :param
clause, subsequent invocations with non-null values result inORA-01722: invalid number
due to what seems to be an incorrectly cached parameter type.Existing code is behaving fine under Spring Boot 2.7.13, Hibernate 5.x.
I am unsure whether this is a Spring Data JPA issue or a Hibernate 6.x issue, however in my very basic reproduction using
EntityManager.createQuery()
within the repository linked to below the issue does not occur whereas with theJpaRepository
backed one it does.Steps to Reproduce the Problem
A repository re-producing the issue can be found here: adrianhj/spring-data-jpa-3060
We have a simple entity, specifying a boolean field with an
AttributeConverter
mapping to Y/N in the database:This entity is backed by the following repository with a query short-circuiting on null values to optionally apply the filter:
Invoke the repository twice, first passing
null
, then passingtrue
:Expected Behaviour
Actual Behaviour
true
fails withjava.sql.SQLSyntaxErrorException: ORA-01722: invalid number
Specifications
Additional Information
For the re-producible example, the following snippets from the log may be of interest:
Generated SQL looks fine:
When using a Spring Data JPA repository, it looks like when invoking with
null
first it is resolving the parameter to aBOOLEAN
type at Hibernate level:This seems to be cached as the subsequent invocation with a non-null value then re-uses the type:
Whereby Oracle falls over with
ORA-01722: invalid number
.Reversing the order of invoking using a non-null value first the type seems to be correctly resolved and cached:
Utilising an EntityManager to run the same query via the same JPQL invoking with a null boolean, then a non-null boolean seem to behave correctly:
The text was updated successfully, but these errors were encountered: