0

I have been struggling for 10 hours over an issue that is driving me insane.

Per https://learn.microsoft.com/en-us/sql/connect/jdbc/using-basic-data-types?view=sql-server-2017

The datetime type maps from SQL to Java as the java.sql.Timestamp type. I know the error comes from the Timestamp mapping because removing that column from the query and constructor works.

Here is the @SqlResultMapping:

@SqlResultSetMapping(
    name = "PoemMap",
    classes = @ConstructorResult(
            targetClass = PoemOutDto.class,
            columns = {
                    @ColumnResult(name = "id", type = BigDecimal.class),
                    @ColumnResult(name = "title"),
                    @ColumnResult(name = "category"),
                    @ColumnResult(name = "description"),
                    @ColumnResult(name = "publication_year", type = Integer.class),
                    @ColumnResult(name = "publication_stmt"),
                    @ColumnResult(name = "source_desc"),
                    @ColumnResult(name = "period"),
                    @ColumnResult(name = "form"),
                    @ColumnResult(name = "confirmed", type = boolean.class),
                    @ColumnResult(name = "confirmed_at", type = Timestamp.class),
                    @ColumnResult(name = "confirmed_by"),
                    @ColumnResult(name = "pending_revision", type = boolean.class),
                    @ColumnResult(name = "author_id", type = BigDecimal.class),
                    @ColumnResult(name = "first_name"),
                    @ColumnResult(name = "last_name"),
                    @ColumnResult(name = "poem_text")
            }
    )

)

Here is the query:

    public List getAll() {
    LOGGER.debug("Returning all poems.");

    Query query = em.createNativeQuery("SELECT poem.id,\n" +
            "\t   poem.title,\n" +
            "\t   poem.category,\n" +
            "\t   poem.description, \n" +
            "\t   poem.publication_year,\n" +
            "\t   poem.publication_stmt,\n" +
            "\t   poem.source_desc,\n" +
            "\t   poem.period,\n" +
            "\t   poem.form,\n" +
            "\t   poem.confirmed,\n" +
            "\t   poem.confirmed_at, \n" +
            "\t   poem.confirmed_by, \n" +
            "\t   poem.pending_revision,\n" +
            "\t   poem.author_id,\n" +
            "\t   [author].[first_name],\n" +
            "\t   [author].[last_name],\n" +
            "\t   SUBSTRING(\n" +
            "\t\t   (\n" +
            "\t\t\t   SELECT ' ' + poem_text.text + '\n' AS [text()]\n" +
            "\t\t\t   FROM [dbo].[poem_text] poem_text\n" +
            "\t\t\t   WHERE poem_text.poem_id = poem.id\n" +
            "\t\t\t   FOR XML PATH('')\n" +
            "\t\t   ), 2, 1000) [poem_text]\n" +
            "\t   FROM [dbo].[poem] poem\n" +
            "\t   INNER JOIN [author] ON poem.author_id = [author].[id]", "PoemMap");
    List resultList = query.getResultList();
    LOGGER.debug(resultList);
    return resultList;

}

And here is the POJO the query is supposed to map onto:

    @JsonSerialize
public class PoemOutDto {
    private BigDecimal id;
    private String title;
    private String category;
    private String description;
    private Integer publicationYear;
    private String publicationStmt;
    private String sourceDesc;
    private String period;
    private String form;
    private Confirmation confirmation;
    private Author author;
    private String text;

    public PoemOutDto(BigDecimal id, String title, String category, String description, Integer publicationYear,
                      String publicationStmt, String sourceDesc, String period, String form, boolean confirmed,
                      Timestamp confirmedAt, String confirmedBy, boolean pendingRevision, BigDecimal authorId,
                      String firstName, String lastName, String text) {
        this.id = id;
        this.title = title;
        this.category = category;
        this.description = description;
        this.publicationYear = publicationYear;
        this.publicationStmt = publicationStmt;
        this.sourceDesc = sourceDesc;
        this.period = period;
        this.form = form;
        this.confirmation = new Confirmation();
        this.confirmation.setConfirmed(confirmed);
        this.confirmation.setConfirmedAt(confirmedAt);
        this.confirmation.setConfirmedBy(confirmedBy);
        this.confirmation.setPendingRevision(pendingRevision);
        this.author = new Author();
        this.author.setId(authorId.longValue());
        this.author.setFirstName(firstName);
        this.author.setLastName(lastName);
        this.text = text;
    }

Getters/Setters ommited.

Attempting to run this query results in the following error:

java.lang.IllegalArgumentException: Could not locate appropriate constructor on class : com.sonnets.sonnet.persistence.dtos.poetry.PoemOutDto

I am at a total loss. Maybe I'm missing something?

Thanks for your help in advance.

Full stack trace:

java.lang.IllegalArgumentException: Could not locate appropriate constructor on class : com.sonnets.sonnet.persistence.dtos.poetry.PoemOutDto
at org.hibernate.loader.custom.ConstructorResultColumnProcessor.resolveConstructor(ConstructorResultColumnProcessor.java:92) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.custom.ConstructorResultColumnProcessor.performDiscovery(ConstructorResultColumnProcessor.java:45) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:482) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.processResultSet(Loader.java:2214) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.getResultSet(Loader.java:2170) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1931) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1893) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:938) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2692) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2675) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.Loader.list(Loader.java:2502) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2200) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1016) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:152) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.query.Query.getResultList(Query.java:146) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at com.sonnets.sonnet.services.PoemService.getAll(PoemService.java:305) ~[classes/:na]
at com.sonnets.sonnet.services.PoemService$$FastClassBySpringCGLIB$$d5a6638e.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746) ~[spring-aop-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at com.sonnets.sonnet.services.PoemService$$EnhancerBySpringCGLIB$$503a365f.getAll(<generated>) ~[classes/:na]
at com.sonnets.sonnet.controllers.PoemController.getAllPoems(PoemController.java:78) ~[classes/:na]
at com.sonnets.sonnet.controllers.PoemController$$FastClassBySpringCGLIB$$5b0f93ea.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684) ~[spring-aop-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at com.sonnets.sonnet.controllers.PoemController$$EnhancerBySpringCGLIB$$485f4288.getAllPoems(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158) ~[spring-boot-actuator-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126) ~[spring-boot-actuator-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111) ~[spring-boot-actuator-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:84) ~[spring-boot-actuator-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176) ~[spring-security-oauth2-2.3.3.RELEASE.jar:na]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135) [na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.base/java.lang.Thread.run(Thread.java:844) [na:na]

The solution:

MS SQL type 'datetime' maps to Java type 'java.util.Date' All that needed to change was the type declaration in the POJO constructor:

    public PoemOutDto(BigDecimal id, String title, String category, String description, Integer publicationYear,
                  String publicationStmt, String sourceDesc, String period, String form, boolean confirmed,
                  java.util.Date confirmedAt, String confirmedBy, boolean pendingRevision, BigDecimal authorId,
                  String firstName, String lastName, String text) 
11
  • Can you please share the full stacktrace? Commented Sep 9, 2018 at 17:42
  • I added it above. Thank you. Commented Sep 9, 2018 at 17:47
  • And I suspect this the column you're having issues with? @ColumnResult(name = "confirmed_at", type = Timestamp.class),. First of all I'm seeing this as missing from the dto itself. Secondly, I would suggest adding a breakpoint within ConstructorResultColumnProcessor.resolveConstructor and check what happens in there. Commented Sep 9, 2018 at 17:49
  • The mismatch occurs from the actual column value vs the field to map to value. Thus doing so will effectively show you the actual column value, thus changing it to the correct one will resolve this. Commented Sep 9, 2018 at 17:51
  • The field itself is mapped onto the Confirmation field. confirmed_at is a field of a Confirmation object. Commented Sep 9, 2018 at 17:53

2 Answers 2

2

This workaround worked for me. Emit the type for the "confirmed_at" column at ColumnResult, also declare "confirmed_at" field in the constructor as Object.class. You may then cast it to Timestamp inside the constructor body when assigning it to an instance variable.

  • Emit the type property for @ColumnResult with name "confirmed_at":
    @SqlResultSetMapping(
     name = "PoemMap",
     classes = @ConstructorResult(
            targetClass = PoemOutDto.class,
            columns = {
                    @ColumnResult(name = "id", type = BigDecimal.class),
                    @ColumnResult(name = "title"),
                    @ColumnResult(name = "category"),
                    @ColumnResult(name = "description"),
                    @ColumnResult(name = "publication_year", type = Integer.class),
                    @ColumnResult(name = "publication_stmt"),
                    @ColumnResult(name = "source_desc"),
                    @ColumnResult(name = "period"),
                    @ColumnResult(name = "form"),
                    @ColumnResult(name = "confirmed", type = boolean.class),
                    // Emit type
                    @ColumnResult(name = "confirmed_at"),
                    @ColumnResult(name = "confirmed_by"),
                    @ColumnResult(name = "pending_revision", type = boolean.class),
                    @ColumnResult(name = "author_id", type = BigDecimal.class),
                    @ColumnResult(name = "first_name"),
                    @ColumnResult(name = "last_name"),
                    @ColumnResult(name = "poem_text")
            }
    )

  • Declare confirm_at as Object.class in constructor and may cast to java.sql.Timestamp:
    public PoemOutDto(BigDecimal id, String title, String category, String description, Integer publicationYear,
                          String publicationStmt, String sourceDesc, String period, String form, boolean confirmed,
                          // Declare as Object
                          Object confirmed_at,
                          String confirmedBy, boolean pendingRevision, BigDecimal authorId,
                          String firstName, String lastName, String text) {
        this.id = id;
        this.title = title;
        this.category = category;
        this.description = description;
        this.publicationYear = publicationYear;
        this.publicationStmt = publicationStmt;
        this.sourceDesc = sourceDesc;
        this.period = period;
        this.form = form;
        this.confirmation = new Confirmation();
        this.confirmation.setConfirmed(confirmed);
        // MAY CAST TO TIMESTAMP
        this.confirmation.setConfirmedAt((Timestamp) confirmed_at);
        this.confirmation.setConfirmedBy(confirmedBy);
        this.confirmation.setPendingRevision(pendingRevision);
        this.author = new Author();
        this.author.setId(authorId.longValue());
        this.author.setFirstName(firstName);
        this.author.setLastName(lastName);
        this.text = text;
    }
Sign up to request clarification or add additional context in comments.

Comments

1

I think that the mismatch you get is attributed from an attempted conversion that between the actual column value vs the field's value.

Adding a breakpoint at ConstructorResultColumnProcessor#resolveConstructor and inspecting the actual column value (and in turn the correcting the field value) should resolve this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.