_Spring-boot 2.0.0.M7
_と_spring-boot-starter-data-elasticsearch
_と_elasticsearch 5
_を使用していますが、LocalDate
フィールドを逆シリアル化するとエラーが発生します。
マイドキュメントは次のようになります。
_@Document(indexName= "myIndex", type = "cluster")
public class Cluster {
@Id
@Field
private Long id;
@Field
private String name;
@Field
private ClusterUrl clusterUrl;
@Field
private ClusterVisible clusterVisible;
}
_
ClusterVisibleは、LocalDates
を保持する子オブジェクトです。
_public class ClusterVisible {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
private LocalDate start;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
private LocalDate end;
}
_
したがって、1つのクラスターIDに対してクエリを実行すると、この例外が発生します。
_com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `Java.time.LocalDate` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"id":12345,"name":"Cluster name ","clusterName":{"de":"Cluster de","it":null,"fr":null},"clusterUrl":{"de":"/url/results","it":null,"fr":null},"clusterVisible":{"start":{"year":2017,"month":"OCTOBER","dayOfMonth":9,"dayOfWeek":"MONDAY","era":"CE","dayOfYear":282,"leapYear":false,"mo"[truncated 252 chars]; line: 1, column: 388] (through reference chain: com.example.elasticsearch5.es.cluster.model.Cluster["clusterVisible"]->com.example.elasticsearch5.es.cluster.model.ClusterVisible["start"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.Java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.Java:1451)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.Java:1027)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.Java:1290)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.Java:326)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.Java:159)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.Java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.Java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.Java:151)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.Java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.Java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.Java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.Java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.Java:2992)
at org.springframework.data.elasticsearch.core.DefaultEntityMapper.mapToObject(DefaultEntityMapper.Java:65)
_
_Java.time api
_にjacksonの依存関係を追加する必要があることは既にわかっているので、追加しました:
_<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
_
しかし、これは今のところ役に立ちません。また、kibanaを使用してクエリを作成し、インデックスのエントリを確認しました。クエリの結果は次のとおりです。
_...
"clusterVisible": {
"start": {
"year": 2017,
"month": "OCTOBER",
"dayOfMonth": 25,
"dayOfWeek": "WEDNESDAY",
"era": "CE",
"dayOfYear": 298,
"leapYear": false,
"monthValue": 10,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
},
"end": {
"year": 3000,
"month": "JANUARY",
"dayOfMonth": 1,
"dayOfWeek": "WEDNESDAY",
"era": "CE",
"dayOfYear": 1,
"leapYear": false,
"monthValue": 1,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
}
}
_
このエラーを修正するのに何が恋しいですか?
追加:正確なエラーは_mapper.mapToObject
_で発生します。そこで、前にnew DefaultEntityMapper();
を数行作成しました。それが問題でしょうか?
_@Override
public Page<Cluster> findClustersAndScoreByText(String text) {
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
.should(QueryBuilders.queryStringQuery(text).lenient(true).defaultOperator(Operator.OR)
.field("name")
.field("svno"));
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder)
.withPageable(PageRequest.of(0, 100)).build();
DefaultEntityMapper mapper = new DefaultEntityMapper();
ResultsExtractor<Page<Cluster>> rs = new ResultsExtractor<Page<Cluster>>() {
@Override
public Page<Cluster> extract(SearchResponse response) {
ArrayList<Cluster> hotels = new ArrayList<>();
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
try {
Cluster cluster = mapper.mapToObject(hit.getSourceAsString(), Cluster.class);
cluster.setScore(hit.getScore());
hotels.add(cluster);
} catch (IOException e) {
e.printStackTrace();
}
}
return new PageImpl<>(hotels, PageRequest.of(0, 100), response.getHits().getTotalHits());
}
};
return elasticsearchTemplate.query(nativeSearchQuery, rs);
}
_
フィールドLocalDateの下に注釈を追加します
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate start;
日付/時刻形式、ISO 8601によると"YYYY-MM-DD"であるため、パターンは次のようになります。
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
代わりに:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
別の方法は、application.ymlを追加することです
spring:
jackson:
serialization:
WRITE_DATES_AS_TIMESTAMPS: false
または、オブジェクトマッパーでこの機能を直接無効にします。
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)