简体   繁体   English

无法构造`java.time.LocalDate` 的实例 - Spring boot、elasticseach、jackson

[英]Cannot construct instance of `java.time.LocalDate` - Spring boot, elasticseach, jackson

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.M7spring-boot-starter-data-elasticsearch Spring-boot 2.0.0.M7Spring-boot 2.0.0.M7 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.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)

I already know that I need to add some jackson dependencies for the java.time api so I added:我已经知道我需要为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>

But this does not help for now.但这暂时没有帮助。 I also checked the entry in the index by making a query using kibana.我还通过使用 kibana 进行查询来检查索引中的条目。 The result of the query is:查询的结果是:

...
"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 .另外:确切的错误发生在mapper.mapToObject So I created a new DefaultEntityMapper();所以我创建了一个new DefaultEntityMapper(); some lines before.前几行。 Could that be the issue?这可能是问题吗?

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

add below annotation over the field LocalDate在 LocalDate 字段上添加以下注释

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate start;

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:
    jackson:
        serialization:
            WRITE_DATES_AS_TIMESTAMPS: false

Or disable this feature directly in your object mapper:或者直接在您的对象映射器中禁用此功能:

objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)

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;
    }

You don't need @JsonFormat .你不需要@JsonFormat All you need is DateFormat.date param in annotation (kotlin):您只需要注释中的DateFormat.date参数(kotlin):

@Field(type = Date, format = date)
val created: LocalDate = now()

Elasticsearch doesn't use Jackson but instead a MappingElasticsearchConverter . Elasticsearch 不使用 Jackson 而是使用MappingElasticsearchConverter

Date will be saved in elastic in format: 2020-01-02 , mapping will be:日期将以弹性格式保存: 2020-01-02 ,映射将为:

 "created" : {
          "type" : "date",
          "format" : "date"
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Jackson 使用 Spring 引导 2 和 Kotlin 反序列化,无法构造 `java.time.LocalDate` 的实例 - Jackson deserialization with Spring Boot 2 and Kotlin, Cannot construct instance of `java.time.LocalDate` 修复 Jackson 无法构造 Java.time.LocalDate 的实例 - Fix Jackson cannot construct instance of Java.time.LocalDate com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造`java.time.LocalDate的实例 - com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate 在 java 日期格式:com.fasterxml.jackson.databind.exc.InvalidDefinition.timeException:无法构造实例的`LocalDatejava. - in java date format: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` 无法构造 `java.time.LocalDate` 的实例(没有创建者,如默认构造,存在):无法从对象值反序列化 - Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): cannot deserialize from Object value Hibernate 4使用java.time.LocalDate和DATE()构造 - Hibernate 4 with java.time.LocalDate and DATE() construct Spring Boot - Jersey 客户端 - Jackson 无法构造 `java.time.Instant` 的实例 - Spring Boot - Jersey Client - Jackson Cannot construct instance of `java.time.Instant` 将 java.sql.Date 转换为 java.time.LocalDate 时出现 Java spring boot Jpa 错误 - Java spring boot Jpa error while converting java.sql.Date to java.time.LocalDate 使用Jackson将java.time.localdate序列化为json - Serialize java.time.localdate into json using Jackson 无法反序列化“java.time.LocalDate”类型的值 - Cannot deserialize value of type `java.time.LocalDate`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM