I am not able to deserialize OffsetDateTime
in spring data elasticsearch when I am simply getting document from the cluster. There are some approaches how to solve the issue, but mostly valid for the previous versions of Spring boot. As well in the current snapshot release of spring-data-elasticsearch the jackson mapper is removed and replaced by some mapper class.
May somebody please give me a hint how to solve this properly with current version of boot + elastic 6.x/7.x ?
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.OffsetDateTime` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
I am using REST High level client.
Solution: Solved with custom entity mapper:
public class CustomEntityMapper implements EntityMapper {
private final ObjectMapper objectMapper;
public CustomEntityMapper() {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(LocalDateTime.class, new MillisOrLocalDateTimeDeserializer());
objectMapper = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.enable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.registerModule(javaTimeModule)
;
objectMapper.setVisibility(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
objectMapper.findAndRegisterModules();
}
@Override
public String mapToString(Object object) throws IOException {
return objectMapper.writeValueAsString(object);
}
@Override
public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
return objectMapper.readValue(source, clazz);
}
@Override
public Map<String, Object> mapObject(Object source) {
return null;
}
@Override
public <T> T readObject(Map<String, Object> source, Class<T> targetType) {
return null;
}
}