[JIRA] (HHH-16974) Unsupported tuple comparison combination
by john doe (JIRA)
john doe ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=60c6117... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiODg5ZDVhZDRm... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16974?atlOrigin=eyJpIjoiODg5ZD... ) HHH-16974 ( https://hibernate.atlassian.net/browse/HHH-16974?atlOrigin=eyJpIjoiODg5ZD... ) Unsupported tuple comparison combination ( https://hibernate.atlassian.net/browse/HHH-16974?atlOrigin=eyJpIjoiODg5ZD... )
Issue Type: Bug Affects Versions: 6.3.0.CR1 Assignee: Unassigned Attachments: image-20230722-214724.png, image-20230722-214730.png Components: hibernate-core Created: 22/Jul/2023 15:17 PM Environment: hibernate 6.3.0.CR1
h2 2.2.220
mysql-connector-j 8.1.0
spring boot 3.2.0-M1
java 20 Priority: Major Reporter: john doe ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=60c6117... )
I have the following three spring data queries:
@Query(
"""
SELECT c
FROM C c
WHERE
c.o = :o AND
(c.p = NULL OR c.p = :p) AND
c.date >= :today
""")
List<CalendarConsultation> findAllForX(O o, P p, LocalDate today);
@Query(
"""
SELECT c
FROM C c
WHERE
c.o = :o AND
c.date >= :today
""")
List<CalendarConsultation> findAllForY(O o, LocalDate today);
@Query(
"""
SELECT c
FROM C c
WHERE
c.o = :o AND
c.p = :p AND
c.date >= :today
""")
List<CalendarConsultation> findAllForZ(O o, P p, LocalDate today);
In 6.2.6 and 6.2.7 all of them are working fine. In 6.3.0.CR1, the first one is failing with the following error:
Caused by: java.lang.IllegalStateException: Unsupported tuple comparison combination. LHS is neither a tuple nor a tuple subquery but RHS is a tuple: org.hibernate.sql.ast.tree.predicate.ComparisonPredicate@7c0d476d
The C.p relationship is a nullable many-to-one going only in one direction:
@Entity
@Table(indexes = @Index(columnList = "o_id,date" ))
public class C extends Id<C> {
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
private O o;
@NotNull private LocalDate date;
@ManyToOne private P p;
}
Doing some very basic debugging shows that in the comparison predicate the rhe indeed changes from an sqm parameter interpretation into an sql tuple with a single entry, which is essentially the same basic attribute mapping as the one in 6.2.7.
6.2.6 / 6.2.7:
6.3.0.CR1:
Full exception stack trace:
org.springframework.dao.InvalidDataAccessApiUsageException: Unsupported tuple comparison combination. LHS is neither a tuple nor a tuple subquery but RHS is a tuple: org.hibernate.sql.ast.tree.predicate.ComparisonPredicate@7c0d476d
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:368)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:234)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:550)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:335)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
at jdk.proxy3/jdk.proxy3.$Proxy257.findAllForX(Unknown Source)
at ___(___.java:87)
at ___(___.java:72)
at ___(___.java:17)
at ___(___.java:32)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:150)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703)
at ___(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:253)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:181)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:918)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:830)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1086)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:165)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at ___(___.java:83)
at ___(___.java:49)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:53)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at ___(___.java:24)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:53)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at ___(___.java:23)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703)
at ___(<generated>)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:85)
at ___(___.java:42)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:53)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:201)
at ___(___.java:148)
at ___(___.java:122)
at ___(___.java:14)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703)
at ___(<generated>)
at ___(___.java:82)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:118)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:93)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:88)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.IllegalStateException: Unsupported tuple comparison combination. LHS is neither a tuple nor a tuple subquery but RHS is a tuple: org.hibernate.sql.ast.tree.predicate.ComparisonPredicate@7c0d476d
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitRelationalPredicate(AbstractSqlAstTranslator.java:7585)
at org.hibernate.sql.ast.tree.predicate.ComparisonPredicate.accept(ComparisonPredicate.java:60)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitJunctionPredicate(AbstractSqlAstTranslator.java:7238)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitJunction(AbstractSqlAstTranslator.java:7216)
at org.hibernate.sql.ast.tree.predicate.Junction.accept(Junction.java:76)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitGroupedPredicate(AbstractSqlAstTranslator.java:6810)
at org.hibernate.sql.ast.tree.predicate.GroupedPredicate.accept(GroupedPredicate.java:33)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitJunctionPredicate(AbstractSqlAstTranslator.java:7238)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitJunction(AbstractSqlAstTranslator.java:7219)
at org.hibernate.sql.ast.tree.predicate.Junction.accept(Junction.java:76)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitWhereClause(AbstractSqlAstTranslator.java:3115)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitQuerySpec(AbstractSqlAstTranslator.java:3061)
at org.hibernate.sql.ast.tree.select.QuerySpec.accept(QuerySpec.java:119)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.visitSelectStatement(AbstractSqlAstTranslator.java:991)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.translateSelect(AbstractSqlAstTranslator.java:854)
at org.hibernate.sql.ast.spi.AbstractSqlAstTranslator.translate(AbstractSqlAstTranslator.java:804)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:376)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:270)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:246)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427)
at org.hibernate.query.Query.getResultList(Query.java:120)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 178 common frames omitted
( https://hibernate.atlassian.net/browse/HHH-16974#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16974#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100232- sha1:4329f54 )
2 years, 8 months
[JIRA] (HHH-16973) optional 'from' clause when result type is an entity class
by Gavin King (JIRA)
Gavin King ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYWFlYjViYWRm... ) / New Feature ( https://hibernate.atlassian.net/browse/HHH-16973?atlOrigin=eyJpIjoiYWFlYj... ) HHH-16973 ( https://hibernate.atlassian.net/browse/HHH-16973?atlOrigin=eyJpIjoiYWFlYj... ) optional 'from' clause when result type is an entity class ( https://hibernate.atlassian.net/browse/HHH-16973?atlOrigin=eyJpIjoiYWFlYj... )
Issue Type: New Feature Assignee: Unassigned Created: 22/Jul/2023 04:31 AM Priority: Major Reporter: Gavin King ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
Panache lets you omit the from clause on a query method, and Stef thinks this is an important feature.
So if we want to re-engineer Panache in terms of the new features of the Metamodel Generator, then we’ll need to add this feature to @HQL methods.
@HQL( "where title like %title" )
List<Book> booksByTitle( String title);
Now, of course, we can have the annotation processor do concatenation on the query string to achieve this, but that’s a bit ugly and makes error reporting a bit trickier. In general I want the annotation processor to do as little as possible, and I prefer to make sure that the things it does can be done via programmatic APIs. Among other motivations, this means it’s easier to migrate from generated to handwritten code, which is something I’m focussed on.
So, I propose that we allow things like this:
session.createSelectionQuery( "where title like %title" , Book.class)
.setTitle( "title" , title)
.getResultList()
Where the from Book is implied.
At first I was not very keen on the idea, but after some consideration I believe I’ve changed my mind. There’s nothing wrong with the code above, and I really do start to see that argument that from Book is just ceremony here.
Naturally, when the result class is missing, or is not an entity, we would require explicit from.
( https://hibernate.atlassian.net/browse/HHH-16973#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16973#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100232- sha1:4329f54 )
2 years, 8 months
[JIRA] (HHH-16969) An entity with a parent <-> child relationship on itself with a natural id does not load using it natural id
by Patrice CAVEZAN (JIRA)
Patrice CAVEZAN ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=63d0ef2... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiMzViOWQwZDBm... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16969?atlOrigin=eyJpIjoiMzViOW... ) HHH-16969 ( https://hibernate.atlassian.net/browse/HHH-16969?atlOrigin=eyJpIjoiMzViOW... ) An entity with a parent <-> child relationship on itself with a natural id does not load using it natural id ( https://hibernate.atlassian.net/browse/HHH-16969?atlOrigin=eyJpIjoiMzViOW... )
Change By: Patrice CAVEZAN ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=63d0ef2... )
Hi,
While upgrading our stack to spring boot 3 which brings hibernate 6, we just noticed that a feature does not work anymore. All other features (we used) works well so far.
The issue is about having an entity with a child ↔︎ parent relationship on itself (having a foreign key pointing to a primary key of another row in the same table). The problem occurs only using the ability offers by hibernate to load an entity (via hibernate session) by it natural id.
It seems Hibernate try to load recursively the entity attribute which point to itself to build the right SQL query, even if this attribute is mark as {{Lazy}} resulting in the end to a {{java.lang.StackOverflowError}}.
I reproduced the issue on simple project in my personal github account:
[https://github.com/pcavezzan/parent-child-relationship-hibernate-6|https:...]
I almost to forgot to mention but the project is in Kotlin ; but for me, it is not dued to Kotlin.
The entity, we’re trying to load looks like the following (you can see in the project):
{noformat}@Entity
@Table(name = "person")
class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int = 0
@NaturalId
@Column(name = "email", nullable = false, unique = true)
var email: String = ""
var name: String = ""
@ManyToOne(fetch = FetchType.LAZY , cascade = [CascadeType.REMOVE] )
@JoinColumn(name = "parent_id")
var parent: Person? = null
@OneToMany(mappedBy = "parent" , cascade = [CascadeType.REMOVE], orphanRemoval = true )
var children: MutableSet<Person> = mutableSetOf()
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Person
return id == other.id
}
override fun hashCode(): Int {
return id
}
override fun toString(): String {
return "Person(id=$id, email='$email', name='$name')"
}
}{noformat}
Thanks a lot in advance for your help on this.
( https://hibernate.atlassian.net/browse/HHH-16969#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16969#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100232- sha1:4329f54 )
2 years, 8 months