提问者:小点点

Spring数据弹性。时间。即时类杰克逊沙漠化不起作用


以下是我的工作室:

  @NotNull
  private Instant createdOn;

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

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

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

问题是当我查询 elasticsearch 服务器以获取工作室时

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

,我将这些字段映射到我的工作空间,得到以下异常:

    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显式注册到Object Mapper

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

}

需要帮助!


共2个答案

匿名用户

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

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

在读取数据时,会尝试查找可用于创建< code>Instant对象的< code>Instant构造函数。但是< code>Instant没有默认的构造函数,映射器应该使用< code > Instant . ofepochsecond(long,long)方法。这个页面清楚地说明了这个问题,并展示了Jackson Mapper是如何配置的。

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

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

匿名用户

如果我没有完全错的话,你的映射会因为错误的格式而失败。您得到的json如下所示:

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

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