be_better

[Springboot] Type definition error: [simple type, class java.time.LocalDateTime]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "co.. 본문

Springboot/Error 해결

[Springboot] Type definition error: [simple type, class java.time.LocalDateTime]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "co..

NiceTry 2023. 12. 27. 23:21

목차

    에러 내용

    프로젝트 진행 중

    Response Dto에 createdAt, updatedAt 을 리턴하는 코드를 구현했는데 결과값을 확인하는 과정에서 이와같은 에러가 발생했다.

     

    그전까진 잘 작동하다가 ObjectMapper를 Bean으로 등록하고나서 생긴 오류이다.

     

    원인

    LocalDateTime type 직렬화, 역직렬화에 문제가 있어서 생기는 에러이다.

    데이터를 주고받으면서 내부의 MessageConverter의 ObjectMapper가 데이터 형식을 바꾸는데

    ObjectMapper를 빈으로 등록해 사용하게되니 적용이 잘 안된게 원인이라고 생각한다.

     

    해결

    첫번째 해결책

    에러메세지에는

    add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"

    라는 해결책이 나와있는데 이미 자체적으로 적용되어있는 모듈이다. 따라서 gradle에 따로 build할 필요는 없다.

     

    두번째 해결책

    LocalDateTime type을 쓰는 Entity column에 어노테이션 추가

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    @MappedSuperclass
    @EntityListeners(AuditingEntityListener.class)
    public abstract class BaseEntity {
    
      // 생성일자
      @CreatedDate
      @JsonSerialize(using = LocalDateTimeSerializer.class)
      @JsonDeserialize(using = LocalDateTimeDeserializer.class)
      private LocalDateTime createdAt;
    
      // 정보 변경 일자
      @LastModifiedDate
      @JsonSerialize(using = LocalDateTimeSerializer.class)
      @JsonDeserialize(using = LocalDateTimeDeserializer.class)
      private LocalDateTime updatedAt;
    
    }

    나의 경우는 여기까지도 해결이 안됐다.

     

    세번째 해결책

    ObjectMapper Bean 코드 수정

    @Configuration
    public class ObjectMapperConfig {
    
      @Bean
      public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
      }
    
    }

    코드를 수정하고 테스트를 진행해보면 Date Format이 엉망으로 되어있는 것을 볼수있다.

    각각 Year, Month, Day, ... 항목들을 디테일하게 나타낸 것인데 간략하게 보이게 하기 위해서 다음 코드를 삽입한다.

    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    @Configuration
    public class ObjectMapperConfig {
    
      @Bean
      public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        // 추가된 코드
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return objectMapper;
      }
    
    }

     

    그럼 정삭적인 결과값을 확인할 수 있게된다.