无法构造`java.time.LocalDate` 的实例 - Spring boot、elasticseach、jackson
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48868034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot construct instance of `java.time.LocalDate` - Spring boot, elasticseach, Hymanson
提问by Patrick
I'm using Spring-boot 2.0.0.M7
and spring-boot-starter-data-elasticsearch
and elasticsearch 5
and I'm getting an error by deserializing a LocalDate
field.
我正在使用Spring-boot 2.0.0.M7
andspring-boot-starter-data-elasticsearch
并且elasticsearch 5
我通过反序列化一个LocalDate
字段得到一个错误。
My Document looks like that:
我的文档看起来像这样:
@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;
}
Where ClusterVisible is a child object which holds the LocalDates
:
其中 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;
}
So I just make a query for one cluster Id and I get this exception:
所以我只查询一个集群 ID,我得到这个异常:
com.fasterxml.Hymanson.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.Hymanson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.Hymanson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
at com.fasterxml.Hymanson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1290)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.Hymanson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.Hymanson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.Hymanson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.Hymanson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at org.springframework.data.elasticsearch.core.DefaultEntityMapper.mapToObject(DefaultEntityMapper.java:65)
I already know that I need to add some Hymanson dependencies for the java.time api
so I added:
我已经知道我需要为它添加一些 Hymanson 依赖项,java.time api
所以我添加了:
<dependency>
<groupId>com.fasterxml.Hymanson.datatype</groupId>
<artifactId>Hymanson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-databind</artifactId>
<version>2.9.4</version>
</dependency>
But this does not help for now. I also checked the entry in the index by making a query using kibana. The result of the query is:
但这暂时没有帮助。我还通过使用 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"
}
}
}
What do I miss for fixing this error?
修复这个错误我错过了什么?
Addition: The exact error occours at mapper.mapToObject
. So I created a new DefaultEntityMapper();
some lines before. Could that be the issue?
补充:确切的错误发生在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);
}
回答by sanjeevjha
add below annotation over the field LocalDate
在 LocalDate 字段上添加以下注释
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate start;
回答by evdelacruz
Date/time format, according to ISO 8601 is "YYYY-MM-DD", so your pattern should be:
日期/时间格式,根据 ISO 8601 是"YYYY-MM-DD",所以你的模式应该是:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
Instead of:
代替:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
Another way is adding in your application.yml
另一种方法是添加您的application.yml
spring:
Hymanson:
serialization:
WRITE_DATES_AS_TIMESTAMPS: false
Or disable this feature directly in your object mapper:
或者直接在您的对象映射器中禁用此功能:
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
回答by Aliaksandr Shpak
need to install JsonFormat JsonDeserialize JsonSerialize
需要安装 JsonFormat JsonDeserialize JsonSerialize
private LocalDate dateOfBirth;
@PastOrPresent(message = "must be past time or present")
@Column(name = "date_of_birth", nullable = false, columnDefinition = "DATE")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}