【问题标题】:Spring Data Elastic - Java.Time.Instant class Jackson deserliization not workingSpring Data Elastic - Java.Time.Instant 类杰克逊反序列化不起作用
【发布时间】:2020-06-01 12:22:23
【问题描述】:

以下是我的 WorkroomDTO:

  @NotNull
  private Instant createdOn;

  @JsonInclude(JsonInclude.Include.NON_NULL)
  private Instant changedOn;

如您所见,我正在使用 Java 8 Instant 类。 在弹性搜索索引服务器中,我将以下内容存储为 JSON:

  "createdOn": {
    "nano": 877000000,
    "epochSecond": 1579861613
  },
  "changedOn": {
    "nano": 920000000,
    "epochSecond": 1579861613
  },

问题是当我查询弹性搜索服务器以获取工作室时

    return elasticsearchOperations.queryForPage(new NativeSearchQueryBuilder().withQuery(mainQuery)
                                                                          .withPageable(elasticUtils.interceptPageable(searchDto.getPageable(), "name"))
                                                                          .build(),
                                            WorkroomDTO.class);

,我将这些字段映射到我的 WorkroomDTO 我得到以下异常:

    com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.Instant` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"createdOn":{"nano":68000000,"epochSecond":1580127683}

仅供参考:

我创建了一个配置文件,其中明确地将 JavaTimeModule 注册到对象映射器

 @Configuration
public class JacksonConfiguration {

  @Value("${application.serialization.include-type-key:true}")
  private boolean includeTypeKey = true;

  @Bean
  public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.addHandler(new MissingTypeIdHandler());
    if (includeTypeKey) {
      mapper.setMixInResolver(new TypeKeyMixInResolver());
    }
    return mapper;
  }

}

需要帮助!

【问题讨论】:

    标签: spring-boot elasticsearch spring-data-elasticsearch


    【解决方案1】:

    这些数据来自哪里?它是由您的应用程序编写的吗?

    使用的 Jackson 映射器似乎没有注册 jackson-datatype-jsr310 模块。

    在读取数据时,尝试找到Instant 的构造函数,该构造函数可用于创建Instant 对象。但是Instant 没有默认构造函数,Mapper 应该使用Instant.ofEpochSecond(long, long) 方法。 This page pretty 声明了问题并展示了 Jackson Mapper 的配置方式。

    以这种方式存储瞬间,作为具有两个属性的对象,不是在 Elasticsearch 中存储日期的正确方法。您应该阅读 the Elasticsearch documentation 了解 Elastcisearch 如何处理日期/时间字段。将瞬间存储为这样的对象时,您将失去使用基于日期/时间的条件的 Elasticsearch 查询的能力。

    您使用哪个版本的 Spring Data Elasticsearch?由于这样的问题,从即将发布的 4.0 版本开始,Spring Data Elasticsearch 将不再使用 Jackson 映射器进行实体映射。 MappingElasticsearchConverter 支持使用 Elasticsearch 日期格式和 java.time 类。

    【讨论】:

    • 感谢您的回答和建议:
    • 感谢您的回答和建议,数据由我的应用程序存储到elasticsearch索引服务器。我已将 jackson-datatype-jsr310 添加到我的 pom.xml 并尝试将模块注册到 ObjectMapper。但它仍然无法映射到所需的对象工作室。我使用 Spring Data Elasticsearch 3.2.0 ..
    【解决方案2】:

    好吧,如果我没有完全错,您的映射由于格式错误而失败。你得到的 json 看起来像这样:

     "createdOn": {
        "nano": 877000000,
        "epochSecond": 1579861613
      },
      "changedOn": {
        "nano": 920000000,
        "epochSecond": 1579861613
      },
    

    这意味着您有 2 个具有两个属性(nano、epochSecond)的对象“createdOn”和“changedOn”,而您尝试将其映射到一个包含两个名为“createdOn”和“changedOn”的属性的对象。你需要修改它,你有例如一个名为 Entry 的类,具有两个属性(nano、epochSeconds),然后是一个具有两个 Entry 类型属性(createdOn、changedOn)的类

    【讨论】:

      猜你喜欢
      • 2020-06-18
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      • 2019-05-09
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多