Search code examples
javaspringhibernatemany-to-one

Can not set field value by reflection error - hibernate proxy object


I am having real trouble with trying to initialize a proxy hibernate object.

This is the error i am getting:

 Can not set com.application.network.domain.MeteredPoint field com.application.network.domain.AbstractHydrocarbonDataImpl.meteredPoint to com.application.network.domain.AbstractNetworkObject$HibernateProxy$xzIea2nD

some info on the project setup before i go into some of the solutions i have tried.

MonthlyHydrocarbonDataImpl extends AbstractHydrocarbonDataImpl

abstractMeteredPoint extends AbstractNetworkObject and implements MeteredPoint

MeterdPoint extends NgcNetworkObject

here is the MonthlyHydrocarbonDataImpl class

public class MonthlyHydrocarbonDataImpl extends AbstractHydrocarbonDataImpl {

    MonthlyHydrocarbonDataImpl() {
        super();
    }

here is the AbstractHydrocarbonDataImpl class

public class AbstractHydrocarbonDataImpl extends AbstractDomainObject<Long> implements HydrocarbonData {

    protected MeteredPoint meteredPoint;

.....
    public void setMeteredPoint(MeteredPoint meteredPoint) {
        this.meteredPoint = meteredPoint;
    }

    public MeteredPoint getMeteredPoint() {
        return meteredPoint;
    }

The problem and solutions tried:

so i am getting the error

field com.app.network.domain.AbstractHydrocarbonDataImpl.meteredPoint to com.app.network.domain.AbstractNetworkObject$HibernateProxy$VmMKGVdU

This is the query that is returning the error

    @Override
    public HydrocarbonData findByMeteredPointProductAndGasDay(MeteredPoint meteredPoint, Product product, LocalDate gasDay) {

        Criteria criteria = createCriteria();

        criteria.add(Restrictions.eq("meteredPoint", meteredPoint));
        criteria.setFetchMode("meteredPoint", FetchMode.JOIN);
        criteria.add(Restrictions.eq("product", product));
        criteria.add(Restrictions.eq("gasDay", gasDay));

        return (HydrocarbonData) criteria.uniqueResult();
    }

As you can see, i am using the fetchMode.join in my query to try force hibernate to load the entity eagerly instead of lazy loading it but this didn't fix my issue.

I have also tried enabling eager loading by adding fetch="join" into my hbm file but this didn't work either.

monthlyhydrocarbondata.hbm.xml

...
    <class name="com.amor.ngc.application.network.domain.MonthlyHydrocarbonDataImpl" table="MONTHLY_HYDROCARBON_DATA">
        <id name="id" type="java.lang.Long">
            <column name="ID" precision="20" scale="0" not-null="true" />
            <generator class="sequence">
                <param name="sequence">MONTHLY_HC_DATA_ID_SEQ</param>
            </generator>
        </id>
        <many-to-one name="meteredPoint" class="com.amor.ngc.application.network.domain.AbstractNgcNetworkObject">
            <column name="METERED_POINT_ID" not-null="true" />
        </many-to-one>
....

this is the networkobject.hbm.xml - i have not included the config for the joined subclasses but i can if needed. Hopefully this is enough tho

    <class name="com.app.network.domain.AbstractNetworkObject"
       proxy="com.app.network.domain.NetworkObject" 
       table="NETWORK_OBJECT" abstract="true">
        <id name="id" type="java.lang.Long">
            <column name="ID" precision="20" scale="0" />
            <generator class="sequence">
                <param name="sequence">NETWORK_OBJECT_ID_SEQ</param>
            </generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" length="64" not-null="true" />
        </property>

The service class which runs the operations/methods has @Transactional annotation aswell as the method where it is run also having the @Transactional annotation. I do not pass the meteredPoint object outside any layers so i dont think this is the issue.

I have fiddled around with the query to manually intialise each MeteredPoint property returned in the list using Hibernate.initialize() but this didnt resolve the issue either.

if you require further detail, let me know and i can post the needed code

Really struggling with this. If anyone has any ideas, would be greatly appreciated.

here is the full stacktrace incase this helps more:


An error occurred during execution of handler: com.web.mvc.reports.component.ViewDailyComponentDeliveryReportController#display()
org.springframework.orm.hibernate5.HibernateSystemException: Could not set field value [DeliveryPointImpl[name=some value]] value by reflection : [class com.application.network.domain.MonthlyHydrocarbonDataImpl.meteredPoint] setter of com.application.network.domain.MonthlyHydrocarbonDataImpl.meteredPoint; nested exception is org.hibernate.PropertyAccessException: Could not set field value [DeliveryPointImpl[name=BG Beachfield]] value by reflection : [class com.application.network.domain.MonthlyHydrocarbonDataImpl.meteredPoint] setter of com.application.network.domain.MonthlyHydrocarbonDataImpl.meteredPoint
    at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:300)
    at org.springframework.orm.hibernate5.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:102)
    at org.springframework.orm.hibernate5.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:73)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:154)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy69.findByMeteredPointProductAndGasDay(Unknown Source)
    at com.application.network.domain.AbstractMeteredPoint.getDailyHydrocarbonData(AbstractMeteredPoint.java:71)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56)
    at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
    at com.application.network.domain.DeliveryPointImpl$HibernateProxy$P9QY3Fk5.getDailyHydrocarbonData(Unknown Source)
    at com.application.composition.domain.CompositionDataRootImpl.getDailyHydrocarbonData(CompositionDataRootImpl.java:87)
    at com.service.reports.ReportingServiceImpl.isDailyComponentDeliveryReportAvailable_aroundBody10(ReportingServiceImpl.java:459)
    at com.service.reports.ReportingServiceImpl$AjcClosure11.run(ReportingServiceImpl.java:1)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:67)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:73)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:71)
    at com.service.reports.ReportingServiceImpl.isDailyComponentDeliveryReportAvailable(ReportingServiceImpl.java:433)
    at com.web.mvc.reports.component.ViewDailyComponentDeliveryReportController.refresh(ViewDailyComponentDeliveryReportController.java:104)
    at com.web.mvc.reports.component.ViewDailyComponentDeliveryReportController.display(ViewDailyComponentDeliveryReportController.java:98)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1043)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:152)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:156)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:673)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: org.hibernate.PropertyAccessException: Could not set field value [DeliveryPointImpl[name=some value]] value by reflection : [class com.application.network.domain.MonthlyHydrocarbonDataImpl.meteredPoint] setter of com.application.network.domain.MonthlyHydrocarbonDataImpl.meteredPoint
    at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:72)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:681)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:144)
    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:5118)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntityFromEntityEntryLoadedState(TwoPhaseLoad.java:282)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:183)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:151)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1200)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:1001)
    at org.hibernate.loader.Loader.doQuery(Loader.java:959)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
    at org.hibernate.loader.Loader.doList(Loader.java:2850)
    at org.hibernate.loader.Loader.doList(Loader.java:2832)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2664)
    at org.hibernate.loader.Loader.list(Loader.java:2659)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1877)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:370)
    at org.hibernate.internal.CriteriaImpl.uniqueResult(CriteriaImpl.java:392)
    at com.application.network.dao.hibernate.MonthlyDeliveryPointHydrocarbonDataHibernateDao.findByMeteredPointProductAndGasDay(MonthlyDeliveryPointHydrocarbonDataHibernateDao.java:42)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    .. 99 more
Caused by: java.lang.IllegalArgumentException: Can not set com.application.network.domain.MeteredPoint field com.application.network.domain.AbstractHydrocarbonDataImpl.meteredPoint to com.application.network.domain.AbstractNetworkObject$HibernateProxy$xzIea2nD
    at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.base/java.lang.reflect.Field.set(Field.java:780)
    at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:52)
    .. 126 more

edited: for bilak

updated the query to unproxy the meteredPoint object.

I did try this and it didnt work - the error occurs when setting (HydrocarbonData) criteria.uniqueResult();

    public HydrocarbonData findByMeteredPointProductAndGasDay(MeteredPoint meteredPoint, Product product, LocalDate gasDay) {

        Criteria criteria = createCriteria();

        criteria.add(Restrictions.eq("meteredPoint", meteredPoint));
        criteria.add(Restrictions.eq("product", product));
        criteria.add(Restrictions.eq("gasDay", gasDay));

        HydrocarbonData hydrocarbonData = (HydrocarbonData) criteria.uniqueResult();

        // Unproxy the meteredPoint property if it's not null
        if (hydrocarbonData != null && hydrocarbonData.getMeteredPoint() != null) {
            hydrocarbonData.setMeteredPoint((MeteredPoint) Hibernate.unproxy(hydrocarbonData.getMeteredPoint()));
        }

        return hydrocarbonData;
    }

Solution

  • If I got it right, in your configuration, you have declared MeteredPoint as an interface and AbstractNetworkObject as its implementation. In Hibernate, the proxy doesn't actually extend the real object, it implements the same interfaces as the real object.

    When Hibernate proxies AbstractNetworkObject, it returns a NetworkObject proxy, which implements the MeteredPoint interface. This is fine unless you try to set it on meteredPoint in AbstractHydrocarbonDataImpl, which expects an object of type MeteredPoint. As the proxy is not a subclass of AbstractNetworkObject, the assignment fails.

    Maybe it helps, that meteredPoint in AbstractHydrocarbonDataImpl is declared as an interface (or abstract class) that both the proxy and the actual object can be cast to?

    Or did you try to change Hibernate mapping to avoid proxying by setting lazy="false"?

    Or maybe it helps to set the @Target Hibernate annotation on MeteredPoint to specify the implementation class?