Search code examples
javajacksonmicronaut

Micronaut deserialize into LocalDateTime


I've got a request body class that looks like this:

import com.fasterxml.jackson.annotation.JsonFormat;
import io.micronaut.serde.annotation.Serdeable;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDateTime;

@Data
@Serdeable
public class CheckDto {

    ...

    @NotNull
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private LocalDateTime startTime;
}

If I manually deserialize it with Jackson and JSR310, it works fine. If I leave it to Micronaut's reimplementation of Jackson it fails (seems to break when it gets to the space). I can repeat it with a test class:

import io.micronaut.serde.ObjectMapper;
import mypackage.CheckDto;

import java.io.IOException;

public class Test {

    private static final ObjectMapper mapper = ObjectMapper.getDefault();

    public static void main(String[] args) throws IOException {
        String json = "{\"startTime\":\"2023-09-28 17:00\"}";
        CheckDto dto = mapper.readValue(json, CheckDto.class);

        System.out.println(dto.getStartTime());
    }
}

Error:

Exception in thread "main" io.micronaut.serde.exceptions.SerdeException: Error decoding property [LocalDateTime startTime] of type [class mypackage.CheckDto]: Text '2023-09-28 17:00' could not be parsed at index 10
    at io.micronaut.serde.support.deserializers.DeserBean$DerProperty.deserializeAndSetPropertyValue(DeserBean.java:825)
    at io.micronaut.serde.support.deserializers.SimpleObjectDeserializer.deserializeInto(SimpleObjectDeserializer.java:96)
    at io.micronaut.serde.support.deserializers.SimpleObjectDeserializer.deserialize(SimpleObjectDeserializer.java:68)
    at io.micronaut.serde.support.deserializers.SimpleObjectDeserializer.deserializeNullable(SimpleObjectDeserializer.java:78)
    at io.micronaut.serde.jackson.JacksonJsonMapper.readValue0(JacksonJsonMapper.java:130)
    at io.micronaut.serde.jackson.JacksonJsonMapper.readValue(JacksonJsonMapper.java:122)
    at io.micronaut.serde.jackson.JacksonJsonMapper.readValue(JacksonJsonMapper.java:168)
    at io.micronaut.json.JsonMapper.readValue(JsonMapper.java:141)
    at io.micronaut.json.JsonMapper.readValue(JsonMapper.java:168)
    at Test.main(Test.java:12)
Caused by: java.time.format.DateTimeParseException: Text '2023-09-28 17:00' could not be parsed at index 10
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2106)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2008)
    at io.micronaut.serde.support.serdes.DefaultFormattedTemporalSerde.deserialize(DefaultFormattedTemporalSerde.java:71)
    at io.micronaut.serde.support.serdes.DefaultFormattedTemporalSerde.deserialize(DefaultFormattedTemporalSerde.java:35)
    at io.micronaut.serde.Deserializer.deserializeNullable(Deserializer.java:85)
    at io.micronaut.serde.support.deserializers.DeserBean$DerProperty.deserializeAndSetPropertyValue(DeserBean.java:806)
    ... 9 more

Any suggestions? Thanks.

ETA: Perhaps I should point out, I think I had this working under Micronaut 3, I've upgraded to 4 recently.


Solution

  • The annotation processor micronaut-serde-processor wasn't running, that was the cause.

    (I'd moved my dtos out to a separate jar file / maven module, from one that had the annotation processor configured in its pom to one that didn't).