提问人:dynamo 提问时间:10/12/2023 最后编辑:dynamo 更新时间:10/21/2023 访问量:120
无法通过反射错误设置字段值 - 休眠代理对象
Can not set field value by reflection error - hibernate proxy object
问:
我在尝试初始化代理休眠对象时遇到了真正的麻烦。
这是我遇到的错误:
Can not set com.application.network.domain.MeteredPoint field com.application.network.domain.AbstractHydrocarbonDataImpl.meteredPoint to com.application.network.domain.AbstractNetworkObject$HibernateProxy$xzIea2nD
在我进入我尝试过的一些解决方案之前,有关项目设置的一些信息。
MonthlyHydrocarbonDataImpl 扩展了 AbstractHydrocarbonDataImpl
abstractMeteredPoint 扩展了 AbstractNetworkObject 并实现了 MeteredPoint
MeterdPoint 扩展了 NgcNetworkObject
下面是 MonthlyHydrocarbonDataImpl 类
public class MonthlyHydrocarbonDataImpl extends AbstractHydrocarbonDataImpl {
MonthlyHydrocarbonDataImpl() {
super();
}
这里是 AbstractHydrocarbonDataImpl 类
public class AbstractHydrocarbonDataImpl extends AbstractDomainObject<Long> implements HydrocarbonData {
protected MeteredPoint meteredPoint;
.....
public void setMeteredPoint(MeteredPoint meteredPoint) {
this.meteredPoint = meteredPoint;
}
public MeteredPoint getMeteredPoint() {
return meteredPoint;
}
尝试的问题和解决方案:
所以我收到错误
field com.app.network.domain.AbstractHydrocarbonDataImpl.meteredPoint to com.app.network.domain.AbstractNetworkObject$HibernateProxy$VmMKGVdU
这是返回错误的查询
@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();
}
如您所见,我在查询中使用 fetchMode.join 来尝试强制休眠以急切地加载实体而不是延迟加载它,但这并没有解决我的问题。
我还尝试通过在我的 hbm 文件中添加 fetch=“join” 来启用预先加载,但这也没有用。
每月碳氢化合物数据.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>
....
这是 NetworkObject.hbm.xml - 我没有包含连接子类的配置,但如果需要,我可以。希望这已经足够了
<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>
运行操作/方法的服务类具有@Transactional注释,运行它的方法也具有@Transactional注释。我没有将 meteredPoint 对象传递到任何层之外,所以我认为这不是问题所在。
我已经摆弄了查询,以使用 Hibernate.initialize() 手动初始化列表中返回的每个 MeteredPoint 属性,但这也没有解决问题。
如果您需要更多详细信息,请告诉我,我可以发布所需的代码
真的为此苦苦挣扎。如果有人有任何想法,将不胜感激。
以下是完整的堆栈跟踪,以防这有更多帮助:
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
编辑: 对于比拉克
更新了查询以取消代理 meteredPoint 对象。
我确实尝试过这个,但它不起作用 - 设置时发生错误(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;
}
答:
如果我没记错的话,在您的配置中,您已将 MeteredPoint 声明为接口,将 AbstractNetworkObject 声明为其实现。在 Hibernate 中,代理实际上并不扩展真实对象,它实现了与真实对象相同的接口。
当 Hibernate 代理 AbstractNetworkObject 时,它会返回一个 NetworkObject 代理,该代理实现了 MeteredPoint 接口。这很好,除非您尝试在 AbstractHydrocarbonDataImpl 中的 meteredPoint 上设置它,这需要 MeteredPoint 类型的对象。由于代理不是 AbstractNetworkObject 的子类,因此赋值失败。
也许它有帮助,AbstractHydrocarbonDataImpl 中的 meteredPoint 被声明为代理和实际对象都可以转换为的接口(或抽象类)?
或者您是否尝试通过设置 lazy=“false” 来更改 Hibernate 映射以避免代理?
或者,也许在 MeteredPoint 上设置 @Target Hibernate 注解以指定实现类会有所帮助?
评论
AbstractNetworkObject
不是错误告诉您的,它至少需要创建一个适当的代理。MeteredPoint
abstractMeteredPoint
Hibernate.unproxy(meteredPoint)