Запрос репозитория Spring Data Elasticsearch определяет формат входного параметра даты - PullRequest
0 голосов
/ 27 июня 2019

Я использую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

...