Как получить тип PGInterval для правильной десериализации - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь написать Java-приложение для извлечения данных из базы данных postgreSQL с полями интервала и продолжаю получать ошибки, связанные с полем. Урезанная версия программы на https://github.com/sashle63/pg-interval-test

README.md имеет выходные и консольные журналы для варианта в каждой ветви.

Я пробовал два подхода к реализации этой модели

1. Используйте тип PGInterval в postgrsql-42.2.5 на моей модели (основная ветвь) При таком подходе я получаю ответ:

{ "timestamp": "2019-04-30T15:47:24.565+0000", "message": "could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize", "details": "uri=/api/testrecords" }

С консольным журналом:

2019-04-30 11:49:10.899 INFO 38658 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-04-30 11:49:10.899 INFO 38658 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-04-30 11:49:10.899 DEBUG 38658 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2019-04-30 11:49:10.905 DEBUG 38658 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2019-04-30 11:49:10.905 INFO 38658 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
2019-04-30 11:49:10.912 DEBUG 38658 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/api/testrecords", parameters={}
2019-04-30 11:49:10.915 DEBUG 38658 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public java.util.List<com.example.pgintervaltest.model.Tester> com.example.pgintervaltest.controller.TesterController.getAllCategories()
2019-04-30 11:49:10.956 INFO 38658 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-04-30 11:49:11.012 DEBUG 38658 --- [nio-8080-exec-1] org.hibernate.SQL : select tester0_.test_id as test_id1_0_, tester0_.test_interval as test_int2_0_ from tester.tb_testinterval tester0_ Hibernate: select tester0_.test_id as test_id1_0_, tester0_.test_interval as test_int2_0_ from tester.tb_testinterval tester0_
2019-04-30 11:49:11.033 DEBUG 38658 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public org.springframework.http.ResponseEntity<?> com.example.pgintervaltest.exception.GlobalExceptionHandler.globleExcpetionHandler(java.lang.Exception,org.springframework.web.context.request.WebRequest)
2019-04-30 11:49:11.067 DEBUG 38658 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json;q=0.8', given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, /;q=0.8] and supported [application/json, application/+json, application/json, application/+json]
2019-04-30 11:49:11.068 DEBUG 38658 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [com.example.pgintervaltest.exception.ErrorDetails@6b93eefd]
2019-04-30 11:49:11.082 DEBUG 38658 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.orm.jpa.JpaSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize]
2019-04-30 11:49:11.082 DEBUG 38658 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR

2. Я нашел несколько руководств по созданию расширений UserType для Hibernate (ветка usertype) При таком подходе я получаю эту ошибку вместо:

{ "timestamp": "2019-04-30T19:46:17.474+0000", "message": "Could not set field value [PT1H] value by reflection : [class com.example.pgintervaltest.model.Tester.testInterval] setter of com.example.pgintervaltest.model.Tester.testInterval; nested exception is org.hibernate.PropertyAccessException: Could not set field value [PT1H] value by reflection : [class com.example.pgintervaltest.model.Tester.testInterval] setter of com.example.pgintervaltest.model.Tester.testInterval", "details": "uri=/api/testrecords" }

Журнал консоли:

2019-04-30 15:45:18.512 INFO 65583 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-04-30 15:45:18.512 INFO 65583 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-04-30 15:45:18.512 DEBUG 65583 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2019-04-30 15:45:18.518 DEBUG 65583 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2019-04-30 15:45:18.518 INFO 65583 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
2019-04-30 15:45:18.526 DEBUG 65583 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/api/testrecords", parameters={}
2019-04-30 15:45:18.530 DEBUG 65583 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public java.util.List<com.example.pgintervaltest.model.Tester> com.example.pgintervaltest.controller.TesterController.getAllCategories()
2019-04-30 15:45:18.578 INFO 65583 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-04-30 15:45:18.638 DEBUG 65583 --- [nio-8080-exec-1] org.hibernate.SQL : select tester0_.test_id as test_id1_0_, tester0_.test_interval as test_int2_0_ from tester.tb_testinterval tester0_ Hibernate: select tester0_.test_id as test_id1_0_, tester0_.test_interval as test_int2_0_ from tester.tb_testinterval tester0_
2019-04-30 15:45:18.667 DEBUG 65583 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public org.springframework.http.ResponseEntity com.example.pgintervaltest.exception.GlobalExceptionHandler.globleExcpetionHandler(java.lang.Exception,org.springframework.web.context.request.WebRequest)
2019-04-30 15:45:18.706 DEBUG 65583 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json;q=0.8', given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, */*;q=0.8] and supported [application/json, application/*+json, application/json, application/*+json]
2019-04-30 15:45:18.706 DEBUG 65583 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [com.example.pgintervaltest.exception.ErrorDetails@5e18d4c3]
2019-04-30 15:45:18.724 DEBUG 65583 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.orm.jpa.JpaSystemException: Could not set field value [PT1H] value by reflection : [class com.example.pgintervaltest.model.Tester.testInterval] setter of com.example.pgintervaltest.model.Tester.testInterval; nested exception is org.hibernate.PropertyAccessException: Could not set field value [PT1H] value by reflection : [class com.example.pgintervaltest.model.Tester.testInterval] setter of com.example.pgintervaltest.model.Tester.testInterval]
2019-04-30 15:45:18.724 DEBUG 65583 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
2019-04-30 15:46:17.469 DEBUG 65583 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/api/testrecords", parameters={}
2019-04-30 15:46:17.470 DEBUG 65583 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public java.util.List com.example.pgintervaltest.controller.TesterController.getAllCategories()
2019-04-30 15:46:17.472 DEBUG 65583 --- [nio-8080-exec-3] org.hibernate.SQL : select tester0_.test_id as test_id1_0_, tester0_.test_interval as test_int2_0_ from tester.tb_testinterval tester0_ Hibernate: select tester0_.test_id as test_id1_0_, tester0_.test_interval as test_int2_0_ from tester.tb_testinterval tester0_
2019-04-30 15:46:17.474 DEBUG 65583 --- [nio-8080-exec-3] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public org.springframework.http.ResponseEntity com.example.pgintervaltest.exception.GlobalExceptionHandler.globleExcpetionHandler(java.lang.Exception,org.springframework.web.context.request.WebRequest)
2019-04-30 15:46:17.474 DEBUG 65583 --- [nio-8080-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json;q=0.8', given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, /;q=0.8] and supported [application/json, application/+json, application/json, application/+json]
2019-04-30 15:46:17.474 DEBUG 65583 --- [nio-8080-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [com.example.pgintervaltest.exception.ErrorDetails@3bbf1f66]
2019-04-30 15:46:17.475 DEBUG 65583 --- [nio-8080-exec-3] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.orm.jpa.JpaSystemException: Could not set field value [PT1H] value by reflection : [class com.example.pgintervaltest.model.Tester.testInterval] setter of com.example.pgintervaltest.model.Tester.testInterval; nested exception is org.hibernate.PropertyAccessException: Could not set field value [PT1H] value by reflection : [class com.example.pgintervaltest.model.Tester.testInterval] setter of com.example.pgintervaltest.model.Tester.testInterval]
2019-04-30 15:46:17.475 DEBUG 65583 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR

Мои зависимости pom.xml:


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

Моя модель:

@Entity
@Table(name = "tb_testinterval")
public class Tester {

    @Id
    @Column(name = "test_id", nullable = false)
    private Integer testId;

    @Column(name = "test_interval", nullable = false)
    @Type(type = "com.example.pgintervaltest.types.PGIntervalType")
    private PGInterval testInterval;

Когда я выполняю код, я хотел бы видеть что-то вроде этого:

[
{ "testId": 1, "testInterval" : "01:00:00" },
{ "testId": 2, "testInterval" : "02:00:00" },
{ "testId": 3, "testInterval" : "03:00:00" }
]
...