I have been trying to setup a polymorphic relationship between some of the entities in a Spring Boot project for my employer. I recently updated the project to Spring Boot 3 so I could start using Hibernate 6’s improved custom collections. That’s working perfectly, but now I’m getting failures when trying to perist ANY polymorphic entities:
Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getAttributeMetadata()" because the return value of "org.hibernate.sql.results.graph.Fetchable.asAttributeMapping()" is null
java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getAttributeMetadata()" because the return value of "org.hibernate.sql.results.graph.Fetchable.asAttributeMapping()" is null
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$3(LoaderSelectBuilder.java:858)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:764)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:133)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping$AnyValuedResultGraphNode.afterInitialize(DiscriminatedAssociationMapping.java:382)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping$AnyValuedFetch.<init>(DiscriminatedAssociationMapping.java:501)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping.generateFetch(DiscriminatedAssociationMapping.java:339)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping.generateFetch(DiscriminatedAssociationAttributeMapping.java:138)
at org.hibernate.sql.results.graph.FetchParent.generateFetchableFetch(FetchParent.java:108)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$3(LoaderSelectBuilder.java:933)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:764)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:133)
at org.hibernate.sql.results.graph.AbstractFetchParent.afterInitialize(AbstractFetchParent.java:32)
at org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode.afterInitialize(AbstractEntityResultGraphNode.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.createDomainResult(AbstractEntityPersister.java:1204)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.generateSelect(LoaderSelectBuilder.java:467)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.createSelect(LoaderSelectBuilder.java:256)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.createLoadPlan(SingleIdEntityLoaderStandardImpl.java:180)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.resolveLoadPlan(SingleIdEntityLoaderStandardImpl.java:120)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.load(SingleIdEntityLoaderStandardImpl.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.doLoad(AbstractEntityPersister.java:3381)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3371)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:602)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromCacheOrDatasource(DefaultLoadEventListener.java:588)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:557)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:550)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:202)
at org.hibernate.event.internal.DefaultLoadEventListener.loadWithRegularProxy(DefaultLoadEventListener.java:282)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:237)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:106)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:78)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:138)
at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1231)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1219)
at org.hibernate.loader.internal.IdentifierLoadAccessImpl.doLoad(IdentifierLoadAccessImpl.java:194)
at org.hibernate.loader.internal.IdentifierLoadAccessImpl.lambda$load$1(IdentifierLoadAccessImpl.java:160)
at org.hibernate.loader.internal.IdentifierLoadAccessImpl.perform(IdentifierLoadAccessImpl.java:107)
at org.hibernate.loader.internal.IdentifierLoadAccessImpl.load(IdentifierLoadAccessImpl.java:160)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:1024)
at org.hibernate.event.internal.DefaultMergeEventListener.lambda$entityIsDetached$0(DefaultMergeEventListener.java:321)
at org.hibernate.engine.spi.LoadQueryInfluencers.fromInternalFetchProfile(LoadQueryInfluencers.java:79)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:319)
at org.hibernate.event.internal.DefaultMergeEventListener.merge(DefaultMergeEventListener.java:150)
at org.hibernate.event.internal.DefaultMergeEventListener.doMerge(DefaultMergeEventListener.java:143)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:127)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:81)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:848)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:834)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
at jdk.proxy3/jdk.proxy3.$Proxy103.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:613)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:288)
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.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
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:77)
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:391)
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)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:163)
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:223)
at jdk.proxy3/jdk.proxy3.$Proxy110.save(Unknown Source)
at com.example.hibernatepolymorph.HibernatePolymorphApplicationTests.createPropertyHolder(HibernatePolymorphApplicationTests.java:55)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
...
To ensure it was not my code causing this problem, I created a blank Spring Boot 3.0.6 project, with Hibernate 6.1.7.Final, added the exact examples in the Hibernate documentation, and recreated the error on persiting either an @Any or @ManyToAny entity.
I then duplicated the same project, swapped it to Spring Boot 2.6.11, with Hibernate 5.6.15.Final, updated the example classes to fit the previous method for setting up polymorphic relationships, and persisting polymorphic entities worked immediately.
I forced the Spring Boot 3 project to use both Hibernate 6.0.2.Final and 6.2.2.Final, but they both gave me the same Fetchable.asAttributeMapping() is null problem. I also permuted the versions with Spring Boot 3.0.0, but now I get a different problem:
class org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart cannot be cast to class org.hibernate.metamodel.mapping.AttributeMapping (org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart and org.hibernate.metamodel.mapping.AttributeMapping are in unnamed module of loader 'app')
java.lang.ClassCastException: class org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart cannot be cast to class org.hibernate.metamodel.mapping.AttributeMapping (org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart and org.hibernate.metamodel.mapping.AttributeMapping are in unnamed module of loader 'app')
I can provide both of the sample projects, but basically, I can’t get an entity with an @Any or @ManyToAny to work with Hibernate 6 on Spring Boot 3. Can anyone tell me why?
Yes, I saw that other post, however it doesn’t indicate for sure they are using Spring. I’ll reply to that one with a link to this comment.
I have created two repositories on GitHub containing the sample projects I mentioned above. One is using Spring Boot 2.7.11 (Hibernate 5.6.15.Final) while the other uses Spring Boot 3.0.6 (Hibernate 6.1.7.Final). They both contain the example classes from their respective Hibernate documentation for @Any and @ManyToAny associations and a single test class containing the tests from that documentation. Running a diff -r on them will show the only difference between the two repositories is the Spring Boot version and how the @Any relations are setup:
This is all you need to do to reproduce the failure using a Java 17 SDK:
git clone https://github.com/dirkniblick/polymorphOnSpringBoot2.git
cd polymorphOnSpringBoot2/
gradle test --info
cd ..
git clone https://github.com/dirkniblick/polymorphOnSpringBoot3.git
cd polymorphOnSpringBoot3/
gradle test --info
You will see the first one pass and the second one fail:
> Task :test FAILED
HibernatePolymorphApplicationTests > createPropertyRepository() FAILED
java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getAttributeMetadataAccess()" because the return value of "org.hibernate.sql.results.graph.Fetchable.asAttributeMapping()" is null
Oh, yes, I’m sorry. That stacktrace was from my original application which was doing a merge. Here’s a stacktrace from Spring Boot 3 example project trying to save a new@Any entity:
Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getAttributeMetadataAccess()" because the return value of "org.hibernate.sql.results.graph.Fetchable.asAttributeMapping()" is null
java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getAttributeMetadataAccess()" because the return value of "org.hibernate.sql.results.graph.Fetchable.asAttributeMapping()" is null
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$6(LoaderSelectBuilder.java:786)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:698)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:118)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping$AnyValuedResultGraphNode.afterInitialize(DiscriminatedAssociationMapping.java:373)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping$AnyValuedFetch.<init>(DiscriminatedAssociationMapping.java:482)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping.generateFetch(DiscriminatedAssociationMapping.java:330)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping.generateFetch(DiscriminatedAssociationAttributeMapping.java:136)
at org.hibernate.sql.results.graph.FetchParent.generateFetchableFetch(FetchParent.java:105)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$6(LoaderSelectBuilder.java:860)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:698)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:118)
at org.hibernate.sql.results.graph.AbstractFetchParent.afterInitialize(AbstractFetchParent.java:33)
at org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode.afterInitialize(AbstractEntityResultGraphNode.java:100)
at org.hibernate.persister.entity.AbstractEntityPersister.createDomainResult(AbstractEntityPersister.java:1300)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.generateSelect(LoaderSelectBuilder.java:450)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.createSelect(LoaderSelectBuilder.java:177)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.createLoadPlan(SingleIdEntityLoaderStandardImpl.java:180)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.resolveLoadPlan(SingleIdEntityLoaderStandardImpl.java:120)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.load(SingleIdEntityLoaderStandardImpl.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.doLoad(AbstractEntityPersister.java:4416)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4406)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:590)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:563)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:221)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:358)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:110)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:72)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1244)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1232)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.doLoad(IdentifierLoadAccessImpl.java:195)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.lambda$load$1(IdentifierLoadAccessImpl.java:161)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.perform(IdentifierLoadAccessImpl.java:108)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.load(IdentifierLoadAccessImpl.java:161)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:1028)
at org.hibernate.event.internal.DefaultMergeEventListener.lambda$entityIsDetached$0(DefaultMergeEventListener.java:344)
at org.hibernate.engine.spi.LoadQueryInfluencers.fromInternalFetchProfile(LoadQueryInfluencers.java:79)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:342)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:178)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:81)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:830)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
at jdk.proxy3/jdk.proxy3.$Proxy104.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:613)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:621)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
...
When saving a new @ManyToAny, the stacktrace is identical except for this:
...
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping.generateFetch(DiscriminatedAssociationMapping.java:330)
at org.hibernate.metamodel.mapping.internal.DiscriminatedCollectionPart.generateFetch(DiscriminatedCollectionPart.java:134)
at org.hibernate.sql.results.graph.FetchParent.generateFetchableFetch(FetchParent.java:105)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$6(LoaderSelectBuilder.java:860)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:698)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:118)
at org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch.<init>(EagerCollectionFetch.java:107)
at org.hibernate.metamodel.mapping.internal.PluralAttributeMappingImpl.generateFetch(PluralAttributeMappingImpl.java:395)
at org.hibernate.sql.results.graph.FetchParent.generateFetchableFetch(FetchParent.java:105)
...
You are correct though. The SimpleJpaRepository.save() method is calling EntityManager.merge():
at jdk.proxy3/jdk.proxy3.$Proxy104.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:613)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:621)
The first test works successfully, however the second test fails when trying to save the @ManyToAny entity. What’s interesting is the problem this time is new:
May 09, 2023 9:22:23 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 23505, SQLState: 23505
May 09, 2023 9:22:23 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.INTEGER_PROPERTY(ID) ( /* key:2 */ CAST(2 AS BIGINT), 'age', 23)"; SQL statement:
insert into integer_property ("name", "value", id) values (?, ?, ?) [23505-214]
May 09, 2023 9:22:23 AM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Error while committing the transaction
jakarta.persistence.RollbackException: Error while committing the transaction
at app//org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:83)
at app//org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
at app//com.example.hibernatepolymorph.HibernatePolymorphApplicationTests.save(HibernatePolymorphApplicationTests.java:119)
at app//com.example.hibernatepolymorph.HibernatePolymorphApplicationTests.createPropertyRepository(HibernatePolymorphApplicationTests.java:99)
at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base@17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base@17.0.2/java.lang.reflect.Method.invoke(Method.java:568)
at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base@17.0.2/java.util.ArrayList.forEach(ArrayList.java:1511)
at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base@17.0.2/java.util.ArrayList.forEach(ArrayList.java:1511)
at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base@17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base@17.0.2/java.lang.reflect.Method.invoke(Method.java:568)
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 app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: jakarta.persistence.PersistenceException: Converting `org.hibernate.exception.ConstraintViolationException` to JPA `PersistenceException` : could not execute statement
at app//org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:165)
at app//org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:175)
at app//org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:67)
... 87 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at app//org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:60)
at app//org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56)
at app//org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at app//org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
at app//org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
at app//org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:39)
at app//org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3438)
at app//org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:4073)
at app//org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:103)
at app//org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:612)
at app//org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:483)
at java.base@17.0.2/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
at app//org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:480)
at app//org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:329)
at app//org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at app//org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at app//org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1425)
at app//org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:477)
at app//org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2234)
at app//org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1930)
at app//org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439)
at app//org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
at app//org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
at app//org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
... 86 more
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.INTEGER_PROPERTY(ID) ( /* key:2 */ CAST(2 AS BIGINT), 'age', 23)"; SQL statement:
insert into integer_property ("name", "value", id) values (?, ?, ?) [23505-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:508)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.mvstore.db.MVPrimaryIndex.add(MVPrimaryIndex.java:120)
at org.h2.mvstore.db.MVTable.addRow(MVTable.java:519)
at org.h2.command.dml.Insert.insertRows(Insert.java:174)
at org.h2.command.dml.Insert.update(Insert.java:135)
at org.h2.command.dml.DataChangeStatement.update(DataChangeStatement.java:74)
at org.h2.command.CommandContainer.update(CommandContainer.java:169)
at org.h2.command.Command.executeUpdate(Command.java:252)
at org.h2.server.TcpServerThread.process(TcpServerThread.java:408)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:191)
at java.base/java.lang.Thread.run(Thread.java:833)
at app//org.h2.message.DbException.getJdbcSQLException(DbException.java:508)
at app//org.h2.engine.SessionRemote.readException(SessionRemote.java:637)
at app//org.h2.engine.SessionRemote.done(SessionRemote.java:606)
at app//org.h2.command.CommandRemote.executeUpdate(CommandRemote.java:227)
at app//org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:209)
at app//org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:169)
at app//org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
... 105 more
May 09, 2023 9:22:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]
My mistake. I added the clear() method to the original version which wasn’t using merge(). I ran that same code with Hibernate 5.6.15Final and it provided the same exception.
gradle test --info --tests “HibernatePolymorphApplicationTests.createPropertyHolder”
gradle test --info --tests “HibernatePolymorphApplicationTests.createPropertyRepository”
I duplicated the entire project, but with Hibernate 5.6.15Final and the only other difference being how the @Any and @ManyToAny are implemented and the old Hibernate code works perfectly fine. Now, that makes me believe these exceptions in my Spring Boot 3 project are coming from Hibernate, not Spring.
Here’s the stacktrace:
HibernatePolymorphApplicationTests > createPropertyHolder() FAILED
java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getAttributeMetadataAccess()" because the return value of "org.hibernate.sql.results.graph.Fetchable.asAttributeMapping()" is null
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$6(LoaderSelectBuilder.java:786)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:698)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:118)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping$AnyValuedResultGraphNode.afterInitialize(DiscriminatedAssociationMapping.java:373)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping$AnyValuedFetch.<init>(DiscriminatedAssociationMapping.java:482)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationMapping.generateFetch(DiscriminatedAssociationMapping.java:330)
at org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping.generateFetch(DiscriminatedAssociationAttributeMapping.java:136)
at org.hibernate.sql.results.graph.FetchParent.generateFetchableFetch(FetchParent.java:105)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.lambda$createFetchableBiConsumer$6(LoaderSelectBuilder.java:860)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.visitFetches(LoaderSelectBuilder.java:698)
at org.hibernate.loader.ast.internal.LoaderSqlAstCreationState.visitFetches(LoaderSqlAstCreationState.java:118)
at org.hibernate.sql.results.graph.AbstractFetchParent.afterInitialize(AbstractFetchParent.java:33)
at org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode.afterInitialize(AbstractEntityResultGraphNode.java:100)
at org.hibernate.persister.entity.AbstractEntityPersister.createDomainResult(AbstractEntityPersister.java:1300)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.generateSelect(LoaderSelectBuilder.java:450)
at org.hibernate.loader.ast.internal.LoaderSelectBuilder.createSelect(LoaderSelectBuilder.java:177)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.createLoadPlan(SingleIdEntityLoaderStandardImpl.java:180)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.resolveLoadPlan(SingleIdEntityLoaderStandardImpl.java:120)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.load(SingleIdEntityLoaderStandardImpl.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.doLoad(AbstractEntityPersister.java:4416)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4406)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:590)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:563)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:221)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:358)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:110)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:72)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1244)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1232)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.doLoad(IdentifierLoadAccessImpl.java:195)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.lambda$load$1(IdentifierLoadAccessImpl.java:161)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.perform(IdentifierLoadAccessImpl.java:108)
at org.hibernate.loader.access.IdentifierLoadAccessImpl.load(IdentifierLoadAccessImpl.java:161)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:1028)
at org.hibernate.event.internal.DefaultMergeEventListener.lambda$entityIsDetached$0(DefaultMergeEventListener.java:344)
at org.hibernate.engine.spi.LoadQueryInfluencers.fromInternalFetchProfile(LoadQueryInfluencers.java:79)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:342)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:178)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:81)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:830)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816)
at com.example.hibernatepolymorph.HibernatePolymorphApplicationTests.update(HibernatePolymorphApplicationTests.java:130)
at com.example.hibernatepolymorph.HibernatePolymorphApplicationTests.createPropertyHolder(HibernatePolymorphApplicationTests.java:64)
I’m not sure how to go about attaching anything to that ticket. I am trying to sign into your Jira instance, but I never receive any of the verify emails it wants me to.
I added a comment to the JIRA issue linking to your repository, so this is fine. Can you please provide a reproducer for the constraint violation exception and then I’ll create the issue for you.
…and it works. I also updated it to use Spring Boot 3.1.1, which uses Hibernate 6.2.5.Final, and it works too. @beikov, thanks for your help troubleshooting this.