如何不修改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
相关产品推荐
相关产品推荐

