Hello,
this weekend our dependency management switched hibernate + gradle plugin version to 6.6.0.Final, from previously 6.5.2.Final. This caused an unexpected reflection error on our production server:
org.springframework.orm.jpa.JpaSystemException: Error accessing field [public ourcorp.jpa.SkillProfile ourcorp.jpa.UserSkillProfile.skillProfile] by reflection for persistent property [ourcorp.jpa.UserSkillProfile#skillProfile] :
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:341)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:241)
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:160)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165)
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.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
at jdk.proxy2/jdk.proxy2.$Proxy250.refresh(Unknown Source)
...
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [public ourcorp.jpa.SkillProfile ourcorp.jpa.UserSkillProfile.skillProfile] by reflection for persistent property [ourcorp.jpa.UserSkillProfile#skillProfile] : UserSkillProfilePK(skillProfile=10, person=teamcoord, proficiencyLevel=40)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:52)
at org.hibernate.metamodel.mapping.internal.AbstractEmbeddableMapping.getValue(AbstractEmbeddableMapping.java:108)
at org.hibernate.sql.results.graph.embeddable.internal.NonAggregatedIdentifierMappingInitializer.resolveInstanceSubInitializers(NonAggregatedIdentifierMappingInitializer.java:281)
at org.hibernate.sql.results.graph.embeddable.internal.NonAggregatedIdentifierMappingInitializer.resolveInstance(NonAggregatedIdentifierMappingInitializer.java:268)
at org.hibernate.sql.results.graph.embeddable.internal.NonAggregatedIdentifierMappingInitializer.resolveInstance(NonAggregatedIdentifierMappingInitializer.java:46)
at org.hibernate.sql.results.graph.Initializer.resolveInstance(Initializer.java:149)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveInstance(EntityInitializerImpl.java:882)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveInstance(EntityInitializerImpl.java:94)
at org.hibernate.sql.results.graph.Initializer.resolveInstance(Initializer.java:149)
at org.hibernate.sql.results.graph.collection.internal.BagInitializer.resolveInstanceSubInitializers(BagInitializer.java:131)
at org.hibernate.sql.results.graph.collection.internal.AbstractImmediateCollectionInitializer.resolveInstance(AbstractImmediateCollectionInitializer.java:358)
at org.hibernate.sql.results.graph.collection.internal.AbstractImmediateCollectionInitializer.resolveInstance(AbstractImmediateCollectionInitializer.java:42)
at org.hibernate.sql.results.graph.Initializer.resolveInstance(Initializer.java:149)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveInstanceSubInitializers(EntityInitializerImpl.java:599)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveInstance(EntityInitializerImpl.java:888)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveInstance(EntityInitializerImpl.java:94)
at org.hibernate.sql.results.graph.Initializer.resolveInstance(Initializer.java:149)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveInstanceSubInitializers(EntityInitializerImpl.java:599)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKey(EntityInitializerImpl.java:534)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKey(EntityInitializerImpl.java:424)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKey(EntityInitializerImpl.java:94)
at org.hibernate.sql.results.graph.Initializer.resolveKey(Initializer.java:101)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKeySubInitializers(EntityInitializerImpl.java:618)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKey(EntityInitializerImpl.java:498)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKey(EntityInitializerImpl.java:424)
at org.hibernate.sql.results.graph.entity.internal.EntityInitializerImpl.resolveKey(EntityInitializerImpl.java:94)
at org.hibernate.sql.results.internal.StandardRowReader.coordinateInitializers(StandardRowReader.java:235)
at org.hibernate.sql.results.internal.StandardRowReader.readRow(StandardRowReader.java:141)
at org.hibernate.sql.results.spi.ListResultsConsumer.readUnique(ListResultsConsumer.java:283)
at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:195)
at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:35)
at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:224)
at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:102)
at org.hibernate.sql.exec.spi.JdbcSelectExecutor.executeQuery(JdbcSelectExecutor.java:91)
at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:165)
at org.hibernate.loader.ast.internal.SingleIdLoadPlan.load(SingleIdLoadPlan.java:145)
at org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl.load(SingleIdEntityLoaderStandardImpl.java:89)
at org.hibernate.persister.entity.AbstractEntityPersister.doLoad(AbstractEntityPersister.java:3778)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3760)
at org.hibernate.event.internal.DefaultRefreshEventListener.doRefresh(DefaultRefreshEventListener.java:273)
at org.hibernate.event.internal.DefaultRefreshEventListener.lambda$refresh$0(DefaultRefreshEventListener.java:199)
at org.hibernate.engine.spi.LoadQueryInfluencers.fromInternalFetchProfile(LoadQueryInfluencers.java:109)
at org.hibernate.event.internal.DefaultRefreshEventListener.refresh(DefaultRefreshEventListener.java:197)
at org.hibernate.event.internal.DefaultRefreshEventListener.refresh(DefaultRefreshEventListener.java:184)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:109)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:138)
at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1315)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1276)
at org.hibernate.engine.spi.CascadingActions$3.cascade(CascadingActions.java:139)
at org.hibernate.engine.spi.CascadingActions$3.cascade(CascadingActions.java:129)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:550)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:472)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:231)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:584)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:514)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:475)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:231)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:170)
at org.hibernate.event.internal.DefaultRefreshEventListener.refresh(DefaultRefreshEventListener.java:164)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:109)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:55)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1295)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1246)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:364)
at jdk.proxy2/jdk.proxy2.$Proxy235.refresh(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:319)
at jdk.proxy2/jdk.proxy2.$Proxy235.refresh(Unknown Source)
at ourcorp.jpa.JobRepositoryCustomImpl.refresh(JobRepositoryCustom.kt:203)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)
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:768)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
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:768)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)
at ourcorp.jpa.JobRepositoryCustomImpl$$SpringCGLIB$$0.refresh(<generated>)
...
Caused by: java.lang.IllegalArgumentException: Can not get ourcorp.jpa.SkillProfile field ourcorp.jpa.UserSkillProfile.skillProfile on ourcorp.jpa.pk.UserSkillProfilePK
at java.base/jdk.internal.reflect.MethodHandleFieldAccessorImpl.newGetIllegalArgumentException(MethodHandleFieldAccessorImpl.java:86)
at java.base/jdk.internal.reflect.MethodHandleObjectFieldAccessorImpl.get(MethodHandleObjectFieldAccessorImpl.java:61)
at java.base/java.lang.reflect.Field.get(Field.java:444)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:48)
this happens during the jpa refresh operation of a loaded entity - after calling a modifying legacy stored procedure for the entity. The fun fact is that the entities complained above are linked through a couple of manyToOnes that are marked as fetch lazy
and shouldn’t be a problem in the first place.
So I was then comparing the traced queries between version 6.5.2 and 6.6.0 and the result shows that lazy loading was no longer applied with the refresh operation.
So my first assumption is that either the gradle hibernate enhancer plugin stopped working as expected, or something in JPA query optimizer goes really wrong.
Our codebase uses Kotlin 1.9 sources.
Please advise.