New Elasticsearch 8 Java API - Insert date time field

I am using the new Elasticsearch 8 Java client API to persist document that contains datetime field. Also, this is a spring boot application.
The issue I got is, if I set a field as LocalDateTime, and try to save to Elasticsearch, it throw exception as follows:
Java Code

// model
public class TestEntity() {
        private LocalDateTime startDatetime;
}

// service
        esClient.index(i -> i
            .index("test-entity")
            .document(testEntity)
        );

I got the following errors:

jakarta.json.JsonException: Jackson exception
    ......
	at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: govonca.lrc.omndmnrf.geology.textsearch.model.job.EtlJobHistory["start-datetime"])
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.13.3.jar:2.13.3]
	......

I added the following dependency

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

and tried add the following custom ObjectMapper, but it does not resolve the problem

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }

Any help will be greatly appreciated.
Thanks

I figured out how to handle this, but I am not sure this is the best way.
The following dependency and @Bean ARE NOT needed.

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

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }

Create Json serializer and deserializer.

public class LocalDatetimeDeserializer extends JsonDeserializer<LocalDateTime> {

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctx)
        throws IOException {
        String str = p.getText();
        try {
            return LocalDateTime.parse(str, DateUtils.DEFAULT_DATETIME_PATTERN);
        } catch (DateTimeParseException e) {
            System.err.println(e);
            return null;
        }
    }
}

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider)
        throws IOException {
        try {
            String s = value.format(DateUtils.DEFAULT_DATETIME_PATTERN);
            gen.writeString(s);
        } catch (DateTimeParseException e) {
            System.err.println(e);
            gen.writeString("");
        }
    }
}

And annotate the LocalDateTime field as following:

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDatetimeDeserializer.class)
    private LocalDateTime startDatetime;
1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.