Hi @igdianov, we have encountered an error when issuing singular queries with embedded IDs which are annotated with a JPA Converter. The original type of one of the embeddable ID fields (in our case LocalDate) was lost during the flattenEmbeddedIdArguments method and is causing an issue with the JPA where it is expecting a LocalDate but a String is being passed to the relational value converter.
To Reproduce
Steps to reproduce the behavior:
Create an Entity class with an embeddable ID.
Create an Embeddable ID class, including a LocalDate field.
Create a JPA Converter class which transforms from String to LocalDate.
Annotate the LocalDate field with the converter.
Run a singular query (get by ID) including the LocalDate field.
Expected behavior
The parameter is passed to the converter in the convertToDatabaseColumn as a LocalDate rather than a String.
Screenshots
2023-06-26T17:33:55.214+02:00 INFO 2564 --- [nio-8080-exec-1] c.i.g.j.q.s.impl.GraphQLJpaQueryFactory :
GraphQL JPQL Single Result Query String:
2023-06-26T17:33:55.301+02:00 ERROR 2564 --- [nio-8080-exec-1] s.g.e.ExceptionResolversExceptionHandler : Unresolved PersistenceException for executionId 100b72db-2def-819e-70b5-dcf6b4aa724f
jakarta.persistence.PersistenceException: Error attempting to apply AttributeConverter
at org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl.toRelationalValue(JpaAttributeConverterImpl.java:105) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.type.internal.ConvertedBasicTypeImpl.disassemble(ConvertedBasicTypeImpl.java:316) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.metamodel.mapping.Bindable.forEachJdbcValue(Bindable.java:149) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.sql.exec.spi.JdbcParameterBindings.registerParametersForEachJdbcValue(JdbcParameterBindings.java:92) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.sql.exec.spi.JdbcParameterBindings.registerParametersForEachJdbcValue(JdbcParameterBindings.java:82) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.SqmUtil.createValueBindings(SqmUtil.java:394) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:326) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:393) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:300) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:276) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:571) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:363) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1073) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.spi.AbstractSelectionQuery.getSingleResult(AbstractSelectionQuery.java:457) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.QuerySqmImpl.getSingleResult(QuerySqmImpl.java:1103) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaQueryFactory.querySingleResult(GraphQLJpaQueryFactory.java:280) ~[graphql-jpa-query-schema-1.0.2-SNAPSHOT.jar:1.0.2-SNAPSHOT]
at com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSimpleDataFetcher.get(GraphQLJpaSimpleDataFetcher.java:48) ~[graphql-jpa-query-schema-1.0.2-SNAPSHOT.jar:1.0.2-SNAPSHOT]
at org.springframework.graphql.execution.ContextDataFetcherDecorator.lambda$get$0(ContextDataFetcherDecorator.java:76) ~[spring-graphql-1.1.3.jar:1.1.3]
at io.micrometer.context.ContextSnapshot.lambda$wrap$1(ContextSnapshot.java:92) ~[context-propagation-1.0.2.jar:1.0.2]
at org.springframework.graphql.execution.ContextDataFetcherDecorator.get(ContextDataFetcherDecorator.java:76) ~[spring-graphql-1.1.3.jar:1.1.3]
at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:282) ~[graphql-java-19.5.jar:na]
at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:211) ~[graphql-java-19.5.jar:na]
at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:59) ~[graphql-java-19.5.jar:na]
at graphql.execution.Execution.executeOperation(Execution.java:159) ~[graphql-java-19.5.jar:na]
at graphql.execution.Execution.execute(Execution.java:105) ~[graphql-java-19.5.jar:na]
at graphql.GraphQL.execute(GraphQL.java:645) ~[graphql-java-19.5.jar:na]
at graphql.GraphQL.lambda$parseValidateAndExecute$11(GraphQL.java:564) ~[graphql-java-19.5.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309) ~[na:na]
at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:559) ~[graphql-java-19.5.jar:na]
at graphql.GraphQL.executeAsync(GraphQL.java:527) ~[graphql-java-19.5.jar:na]
at org.springframework.graphql.execution.DefaultExecutionGraphQlService.lambda$execute$2(DefaultExecutionGraphQlService.java:82) ~[spring-graphql-1.1.3.jar:1.1.3]
at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:47) ~[reactor-core-3.5.5.jar:3.5.5]
at reactor.core.publisher.Mono.subscribe(Mono.java:4485) ~[reactor-core-3.5.5.jar:3.5.5]
at reactor.core.publisher.Mono.subscribeWith(Mono.java:4551) ~[reactor-core-3.5.5.jar:3.5.5]
at reactor.core.publisher.Mono.toFuture(Mono.java:5063) ~[reactor-core-3.5.5.jar:3.5.5]
at org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar.lambda$registerAdapters$5(ReactiveAdapterRegistry.java:244) ~[spring-core-6.0.8.jar:6.0.8]
at org.springframework.core.ReactiveAdapter.fromPublisher(ReactiveAdapter.java:121) ~[spring-core-6.0.8.jar:6.0.8]
at org.springframework.web.servlet.function.DefaultAsyncServerResponse.create(DefaultAsyncServerResponse.java:186) ~[spring-webmvc-6.0.8.jar:6.0.8]
at org.springframework.web.servlet.function.ServerResponse.async(ServerResponse.java:250) ~[spring-webmvc-6.0.8.jar:6.0.8]
at org.springframework.graphql.server.webmvc.GraphQlHttpHandler.handleRequest(GraphQlHttpHandler.java:111) ~[spring-graphql-1.1.3.jar:1.1.3]
at org.springframework.web.servlet.function.support.HandlerFunctionAdapter.handle(HandlerFunctionAdapter.java:107) ~[spring-webmvc-6.0.8.jar:6.0.8]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.8.jar:6.0.8]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.8.jar:6.0.8]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.8.jar:6.0.8]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.8.jar:6.0.8]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.8.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.8.jar:6.0.8]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.8.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.8.jar:10.1.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.8.jar:6.0.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.8.jar:6.0.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.8.jar:6.0.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.8.jar:6.0.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.8.jar:6.0.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.8.jar:6.0.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.8.jar:10.1.8]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.time.LocalDate (java.lang.String and java.time.LocalDate are in module java.base of loader 'bootstrap')
at com.rs2.dl.data.api.converters.DateConverter.convertToDatabaseColumn(DateConverter.java:9) ~[main/:na]
at org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl.toRelationalValue(JpaAttributeConverterImpl.java:99) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
... 81 common frames omitted
**Desktop (please complete the following information):**
- OS: Windows
- Browser: Chrome
- Version: 1.0.1-SNAPSHOT
Describe the bug
Hi @igdianov, we have encountered an error when issuing singular queries with embedded IDs which are annotated with a JPA Converter. The original type of one of the embeddable ID fields (in our case LocalDate) was lost during the flattenEmbeddedIdArguments method and is causing an issue with the JPA where it is expecting a LocalDate but a String is being passed to the relational value converter.
To Reproduce Steps to reproduce the behavior:
Expected behavior The parameter is passed to the converter in the convertToDatabaseColumn as a LocalDate rather than a String.
Screenshots
2023-06-26T17:33:55.214+02:00 INFO 2564 --- [nio-8080-exec-1] c.i.g.j.q.s.impl.GraphQLJpaQueryFactory : GraphQL JPQL Single Result Query String: