39

I am having a tough time understanding java.time.Instant library. I am not sure where there is not a straightforward solution way to implement Instant library. I have a spring-boot project where I have created RESTful service with CRUD operation on MongoDB. Everything was ok until I introduced Instant updatedOn & Instant createdOn in DTO.

Here sample code of my POST response where failure is occurring.

  @Override
  public ResponseEntity<ResponseDto> create(@RequestBody CLMDto CLMDto) {

    CLMDto createdCLMDto =
        CLMService.create(CLMDto);

    return ResponseEntity.status(HttpStatus.CREATED)
        .header(
            RESPONSE_HEADER_LOCATION, CLM_URL + "/" + createdCLMDto.getId())
        .body(ResponseDto.builder().value(createdCLMDto).build()); //--------------------->**Failing here**
  }

My response DTO looks something like this


@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class ResponseDto {

  private Integer count;
  private Object value;
  private Object error;
  private Object info;
}

and CLMDto

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AdminDataDto {
  
  private Instant createdOn;
  private Instant updatedOn;
  @JsonProperty(value = "updatedByName", access = JsonProperty.Access.READ_ONLY)
  private String updatedByName;
}

In debugger, i noticed place where exception is happening variable createdCLMDto has following values

createdOn:Instant@193 "2021-03-27T11:53:24.774765300Z"
updatedByName:test
updatedOn:Instant@195 "2021-03-27T11:53:24.774765300Z"

as I am using Lombok plugins so I can't debug inside and find the root cause on autogenerated code. I am not looking for a solution but a suggestion where things can go wrong here. My exact error is

  Type definition error: [simple type, class java.time.Instant]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Java 8 date/time type `java.time.Instant` not supported by default: add Module \"com.fasterxml.jackson.datatype:jackson-datatype-jsr310\" to enable 
handling (through reference chain: 
com.abc.service.dto.ResponseDto[\"value\"]->com.abc.dto.AdminDataDto[\"createdOn\"])",

Needless to say but I already tried the solution provided here to updated maven libraries but no success. I find many questions on StackOverflow around this library but no one is explaining the easiest way to implement this libarary.

I have already following dependency in pom.xml

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

I have already tried the solution provided here Java 8 date time types serialized as object with Spring Boot

Sharad
  • 838
  • 1
  • 7
  • 15
  • Did you do [this](https://stackoverflow.com/a/47120519/438154)? Show us. – Sotirios Delimanolis Mar 27 '21 at 12:16
  • 2
    What version of spring boot are you using ? – Olivier Boissé Mar 27 '21 at 12:20
  • I am using spring boot version = 2.4.3 – Sharad Mar 27 '21 at 13:23
  • @SotiriosDelimanolis I am not sure about adding a new bean here. Are there any alternatives? Also, I see that answer is not marked as accepted as well so I am a bit reluctant to try this. The one which is accepted, I already tried but didn't work. thanks – Sharad Mar 27 '21 at 13:36
  • I have already tried the solution provided here https://stackoverflow.com/questions/47120363/java-8-date-time-types-serialized-as-object-with-spring-boot but still, this question is marked as close and asking me to create a new question if that doesn't solve the problem. Strange! – Sharad Mar 27 '21 at 13:39
  • 1
    You just have to register the module, just like the error message is telling you. – Sotirios Delimanolis Mar 27 '21 at 13:41
  • I have the same issue, with ZonedDateTime everything worked fine with springboot 2.4.5, stopped working with 2.5.0 – Eran Friedland Jun 17 '21 at 08:31

1 Answers1

38

Do you have the following artifact into your project ?

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

According to the spring source code, if the class com.fasterxml.jackson.datatype.jsr310.JavaTimeModule is present in your classpath, the JavaTimeModule should be registered

Olivier Boissé
  • 15,834
  • 6
  • 38
  • 56
  • 5
    Yes, I already have this dependency in pom.xml . I have updated the question – Sharad Mar 27 '21 at 13:30
  • 40
    Thanks for pointing exact source code. I did it and now it is working @Bean ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); return objectMapper; } – Sharad Mar 27 '21 at 14:31
  • 7
    You shouldn't create the object mapper by yourself, normally spring boot do it for you. Do you have `@SpringBootApplication` annotation in your code (this annotation declare `@EnableAutoConfiguration` which configure your application automatically depending on what you have in your classpath and properties) – Olivier Boissé Mar 27 '21 at 14:43
  • Thanks.This clears my doubt. – Sharad Mar 27 '21 at 15:00
  • 1
    [https://www.baeldung.com/spring-boot-customize-jackson-objectmapper#2-jackson2objectmapperbuildercustomizer](An example of overriding the) `ObjectMapper` instead of re-creating in Spring using `Jackson2ObjectMapperBuilderCustomizer` – Stokedout Dec 23 '21 at 09:18