You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不修改Contract模型将LocalDate以String存入MongoDB

技术栈
  • Java 17
  • Springboot 3.2
  • MongoDB
Contract模型

我使用一个名为Contract的模型,它包含一个类型为LocalDate的属性startDate。

@Data
@Document("contract")
public class Contract {

// ...

  /* shows the start date of the contract */
  @NotNull(message = "The contract start date cannot be null")
  protected LocalDate startDate;

}
架构

应用采用“shared-library”和“contract-service”两个独立项目的架构。shared-lib包含所有模型、验证器和序列化器,作为依赖被引入contract-service。

<dependency>
    <groupId>...</groupId>
    <artifactId>shared-lib</artifactId>
    <version>0.5.31-SNAPSHOT</version>
</dependency>
问题描述

我正在开发一个Spring Boot项目,其中Contract模型类包含一个名为startDate的LocalDate字段。该字段需要以String类型存储在MongoDB中,同时在Java中仍以LocalDate类型处理。

应用中已有大量逻辑将startDate作为LocalDate使用,因此无法修改Contract模型中的数据类型为String。

已尝试方案

我尝试实现自定义序列化器,期望在转换为JSON存入数据库前修改属性类型,但未生效。

无错误信息,序列化器似乎被完全忽略。

JSON序列化器

public class LocalDateToStringSerializer extends StdSerializer<LocalDate> {

    private static final long serialVersionUID = 1L;

    public LocalDateToStringSerializer() {
        super(LocalDate.class);
    }

    @Override
    public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString(value.format(DateTimeFormatter.ISO_LOCAL_DATE));
    }
}
public class StringToLocalDateDeserializer extends JsonDeserializer<LocalDate> {

    @Override
    public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        return LocalDate.parse(p.getValueAsString(), DateTimeFormatter.ISO_LOCAL_DATE);
    }
}

Jackson配置(contract-service)

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDate.class, new LocalDateToStringSerializer());
        module.addDeserializer(LocalDate.class, new StringToLocalDateDeserializer());
        mapper.registerModule(module);
        return mapper;
    }
}

使用序列化器的Contract模型

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

@Data
@Document("contract")
public class Contract {

// ...

  /* shows the start date of the contract */
  @NotNull(message = "The contract start date cannot be null")
  @JsonSerialize(using = LocalDateToStringSerializer.class)
  @JsonDeserialize(using = StringToLocalDateDeserializer.class)
  protected LocalDate startDate;

}

测试代码

这是我搭建的测试类

@Component
@Slf4j
public class ContractDatesConverter implements CommandLineRunner {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void run(String... args) {
        Contract contract = mongoTemplate.findAll(Contract.class).get(0);

        contract.setStartDate(contract.getStartDate().plusDays(1));
        mongoTemplate.save(contract);
    }
}

运行代码后,数据库中的startDate被改回LocalDate类型,且未增加一天。

总结

希望有人能指出我的错误,或提供更直接的解决方案。谢谢!


内容的提问来源于stack exchange,提问作者ronanski11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:07:21