Я используюasticsearch 6.5.3 и Spring Boot 2.1.6 и spring-data -asticsearch 3.2.0.M1.
Я определил конфигурацию Elasticsearch как:
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchRestTemplate(client(), new CustomEntityMapper());
}
public static class CustomEntityMapper implements EntityMapper {
private final ObjectMapper objectMapper;
public CustomEntityMapper() {
//we use this so that Elasticsearch understands LocalDate and LocalDateTime objects
objectMapper = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
//MUST be registered BEFORE calling findAndRegisterModules
.registerModule(new JavaTimeModule())
.registerModule(new Jdk8Module());
//only autodetect fields and ignore getters and setters for nonexistent fields when serializing/deserializing
objectMapper.setVisibility(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
//load the other available modules as well
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);
}
}
У меня есть хранилище с методом, определенным как:
List<AccountDateRollSchedule> findAllByNextRollDateTimeLessThanEqual(final LocalDateTime dateTime);
И POJO AccountDateRollSchedule определяет это поле как:
@Field(type = FieldType.Date, format = DateFormat.date_hour_minute)
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime nextRollDateTime;
Я вижу, что мой индекс правильно имеетэто поле, созданное как объявлено и ожидалось:
"nextRollDateTime": {
"type": "date",
"format": "date_hour_minute"
}
Также запрос индекса возвращает поле, отформатированное, как и ожидалось:
"nextRollDateTime" : "2019-06-27T13:34"
Мой запрос к хранилищу будет преобразован в:
{"query":
{"bool" :
{"must" :
{"range" :
{"nextRollDateTime" :
{"from" : null,
"to" : "?0",
"include_lower" : true,
"include_upper" : true
}
}
}
}
}
}
Но передача любого ввода LocalDateTime методу НЕ соответствует формату, определенному для поля, вместо этого всегда используется формат FULL.Вызов:
findAllByNextRollDateTimeLessThanEqual(LocalDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.MINUTES));
дает мне следующее исключение (любая аннотация @DateTimeFormat или @JsonFormat для параметра метода в хранилище игнорируется):
Unrecognized chars at the end of [2019-07-22T09:07:00.000]: [:00.000]
Если я вместо этого изменю хранилищеметод, принимающий String и передающий String, отформатированный точно так, как ожидается, в качестве входных данных для него, он работает без проблем.
Можно ли как-то определить формат, используемый для параметра даты, переданного во входные данные в метод репозитория илили Spring использовать тот, который сконфигурирован на самом поле?
Я бы не хотел оборачивать этот метод для простого преобразования, подобного этому (я сделал, и это работает), и я также хотел бы избежать использования длинного типа дляполе даты
Спасибо и ура
Для справки я также открываю выпуск на Spring JIRA