2017-02-13 4 views
1

Я использую поддержку Spring Data для Elasticsearch. Здесь отображение временной метки поля:Как сделать Spring Data Elasticsearch работать с java.time.LocalDateTime для даты

@Field(type = FieldType.Date, index = FieldIndex.not_analyzed, store = true, 
     format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ") 
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSSZZ") 
private LocalDateTime timestamp; 

Это приводит к отображению поля в Elasticsearch следующим образом:

"timestamp":{"type":"date","store":true,"format":"yyyy-MM-dd'T'HH:mm:ss.SSSZZ"} 

Когда я использую java.util.Date вместо все работает отлично. Однако, когда я переключаюсь на java.time.LocalDateTime, как указано выше, документ, отправленный в Elasticsearch, вызывает исключение. Вот документ (метка времени поля только для краткости):

"timestamp": { 
    "hour":7, "minute":56, "second":9, "nano":147000000, "year":2017, "month":"FEBRUARY", 
    "dayOfMonth":13, "dayOfWeek":"MONDAY", "dayOfYear":44, "monthValue":2, "chronology": { 
     "id":"ISO", "calendarType": "iso8601" 
    } 
} 

И исключение:

MapperParsingException[failed to parse [timestamp]]; nested: IllegalArgumentException[unknown property [hour]]; 
(...) 
Caused by: java.lang.IllegalArgumentException: unknown property [hour] 

Похоже, что картина игнорируются здесь, когда jsonizing документа. Любые возможные подсказки? Или, может быть, вы знаете, как использовать «встроенное» поле _timestamp с данными Spring?

ответ

1

Проверьте https://github.com/spring-projects/spring-data-elasticsearch/wiki/Custom-ObjectMapper, чтобы добавить JavaTimeModule в ваш ObjectMapper.

@Configuration 
public class ElasticSearchConfiguration { 

    @Bean 
    public ElasticsearchTemplate elasticsearchTemplate(Client client) { 
    return new ElasticsearchTemplate(client, new CustomEntityMapper()); 
    } 

    public static class CustomEntityMapper implements EntityMapper { 

    private final ObjectMapper objectMapper; 

    public CustomEntityMapper() { 
     objectMapper = new ObjectMapper(); 
     objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
     objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); 
     objectMapper.registerModule(new CustomGeoModule()); 
     objectMapper.registerModule(new JavaTimeModule()); 
    } 

    @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); 
    } 
    } 
} 
+0

Это выглядит многообещающе. Любая причина, по которой JavaTimeModule не используется по умолчанию – theadam

+0

Возможно, для поддержки JDK <8 ... Вы можете использовать 'objectMapper.findAndRegisterModules();' для регистрации всех модулей, найденных в пути к классам ... –

Смежные вопросы