@SqlResultSetMapping 使用 Spring JPA 抛出奇怪的异常

Posted

技术标签:

【中文标题】@SqlResultSetMapping 使用 Spring JPA 抛出奇怪的异常【英文标题】:@SqlResultSetMapping thows strange exception with Spring JPA 【发布时间】:2016-07-19 10:25:05 【问题描述】:

我正在尝试使用@SqlResultSetMapping 获得结果,如下所示

@SqlResultSetMapping(name = "SCHOOLWITHOWNER", entities =


    @EntityResult(entityClass = SchoolDto.class, fields =
    
        @FieldResult(name = "id", column = "c_sm_npk_id"),
        @FieldResult(name = "name", column = "c_sm_vnm_name")
    ),
    @EntityResult(entityClass = UserDto.class, fields =
    
        @FieldResult(name = "id", column = "c_um_npk_id"), //
        @FieldResult(name = "firstName", column = "c_um_vnm_first_name"), //
        @FieldResult(name = "lastName", column = "c_um_vnm_last_name")
    )
)

下面是来自 DaoImpl 文件的代码 sn-p。

   getEntityManager().createNativeQuery
    ("SELECT c_sm_npk_id,
             c_sm_vnm_name,
             c_um_npk_id, 
             c_um_vnm_first_name , 
             c_um_vnm_last_name 
      from t_school_master AS  school 
      join t_user_master AS owner 
          ON school.owner_c_um_npk_id = owner.c_um_npk_id",
   "SCHOOLWITHOWNER" ).getResultList();

当我执行上述方法时,我遇到了奇怪的错误:

SEVERE: Servlet.service() for servlet life threw exception
org.postgresql.util.PSQLException: The column name c_sm_vnm2_15_0_ was not found in this ResultSet.
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumn(AbstractJdbc2ResultSet.java:2727)
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getString(AbstractJdbc2ResultSet.java:2567)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getString(HikariProxyResultSet.java)
    at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$2.doExtract(VarcharTypeDescriptor.java:74)
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:267)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:263)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:338)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2969)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1695)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1627)
    at org.hibernate.loader.Loader.getRow(Loader.java:1514)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:725)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:952)
    at org.hibernate.loader.Loader.doQuery(Loader.java:920)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
    at org.hibernate.loader.Loader.doList(Loader.java:2553)
    at org.hibernate.loader.Loader.doList(Loader.java:2539)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
    at org.hibernate.loader.Loader.list(Loader.java:2364)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:353)
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1873)
    at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:311)
    at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:141)
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573)
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449)
    at com.vinayak.education.dao.impl.SchoolDaoImpl.getAllSchoolsWithAdvanceSearch(SchoolDaoImpl.java:39)
    at com.vinayak.education.service.impl.SchoolServiceImpl.getAllSchoolsWithAdvanceSearch(SchoolServiceImpl.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy115.getAllSchoolsWithAdvanceSearch(Unknown Source)
    at com.vinayak.education.rest.SchoolController.getAllSchoolsWithAdvanceSearch(SchoolController.java:112)
    at com.vinayak.education.rest.SchoolController$$FastClassBySpringCGLIB$$aea67306.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at com.vinayak.education.rest.SchoolController$$EnhancerBySpringCGLIB$$bbb7f604.getAllSchoolsWithAdvanceSearch(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:174)
    at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:237)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at com.vinayak.life.security.AuthenticationTokenProcessingFilter.doFilter(AuthenticationTokenProcessingFilter.java:97)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:745)

我不明白 c_sm_vnm2_15_0_ 是从哪里来的?

我做了 show_sql = true 和 hibernate 在查询下面执行

  SELECT
        c_sm_npk_id,
        c_sm_vnm_name,
        c_um_npk_id,
        c_um_vnm_first_name ,
        c_um_vnm_last_name 
    from
        t_school_master AS  school 
    join
        t_user_master AS owner 
            ON school.owner_c_um_npk_id = owner.c_um_npk_id

这在 SQL 中运行良好。

请让我知道我做错了什么。

谢谢

【问题讨论】:

SchoolDto 和 UserDto 的属性是什么?都被resultsetMapping映射了吗? SchoolDto 和 UserDto 中有很多属性,只有一部分是通过resultSetMapping映射的 我认为,虽然不是 100% 肯定,但您需要在映射中指定所有属性。只有@ConstructorResult@ColumnResult 才能获得需要映射的特定属性。 但目前我在 ResultSetMapping 中包含的列出现错误。 是的,我就是这么告诉你的。我认为您需要将所有属性添加到映射中,而不仅仅是您发布的那些。尝试我告诉你的其他解决方案。 100% 确定它正在工作,因为我已经使用过很多次了。 【参考方案1】:

请阅读this

javax.persistence 注解EntityResult

目标:

用于将 SQL 查询的 SELECT 子句映射到实体结果。如果 使用此注解时,SQL 语句应选择所有 映射到实体对象的列。

如果您只想映射某些属性,请使用@ConstructorResult@ColumnResult

【讨论】:

我改为使用@constructorResult 并收到类似“无法在类上找到适当的构造函数:com.vinayak.education.dto.SchoolDto”的错误,我需要 POJO 中的构造函数吗? 是的,您必须定义等效的构造函数。您可以拥有任意数量的组合,但由于您需要特定的列,因此您需要一个等效的构造函数,将这些字段作为具有相同顺序的参数。

以上是关于@SqlResultSetMapping 使用 Spring JPA 抛出奇怪的异常的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate:使用@SqlResultSetMapping 映射本机查询的结果集

如何在 Symfony2,学说 2 中使用 @SqlResultSetMapping?

@SqlResultSetMapping 实体映射中引用的未知列

JPA SqlResultSetMapping 对象顺序

@SqlResultSetMapping 将内部类绑定到目标类

JPA 2.1 @ConstructorResult 和 @SqlResultSetMapping 与 JPQL SELECT NEW SomeConstructor(...) 相比有啥优势?