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

ModelMapper映射POJO到Entity后CosmosDB存储ZonedDateTime格式异常求助

解决方案

原因分析

问题核心在于:POJO上的Jackson注解仅作用于该类的序列化/反序列化,但存入CosmosDB时实际序列化的是POJOEntity对象,而目标类POJOEntity的startTs字段缺少对应的序列化配置,导致CosmosDB使用默认逻辑序列化ZonedDateTime对象。


方案1:给POJOEntity字段添加Jackson序列化注解

直接在POJOEntity的startTs字段上补充序列化注解,确保CosmosDB序列化时采用指定格式:

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.ZonedDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;
import java.time.ZonedDateTime;

// POJOEntity类中的对应字段
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx")
@JsonSerialize(using = ZonedDateTimeSerializer.class)
@JsonDeserialize(using = ZonedDateTimeDeserializer.class)
private ZonedDateTime startTs;

注意:原POJO仅配置了反序列化注解,这里必须补充@JsonSerialize来指定序列化规则。


方案2:全局配置CosmosDB的Jackson ObjectMapper

如果需要统一处理所有ZonedDateTime类型的序列化/反序列化,可通过Spring Bean定制CosmosDB使用的ObjectMapper:

import com.azure.spring.data.cosmos.core.CosmosTemplate;
import com.azure.spring.data.cosmos.core.convert.MappingCosmosConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.ZonedDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.format.DateTimeFormatter;

@Configuration
public class CosmosConfig {

    @Bean
    public CosmosTemplate cosmosTemplate(CosmosClient cosmosClient, CosmosDatabase cosmosDatabase) {
        CosmosTemplate template = new CosmosTemplate(cosmosClient, cosmosDatabase.getId());
        MappingCosmosConverter converter = (MappingCosmosConverter) template.getConverter();
        ObjectMapper objectMapper = converter.getObjectMapper();

        // 注册Java8时间模块,自定义ZonedDateTime的序列化/反序列化规则
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx");
        javaTimeModule.addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer(formatter));
        javaTimeModule.addDeserializer(ZonedDateTime.class, new ZonedDateTimeDeserializer(formatter));
        
        objectMapper.registerModule(javaTimeModule);
        return template;
    }
}

若使用spring-cloud-azure-starter-cosmos,也可通过Jackson2ObjectMapperBuilderCustomizer实现全局配置:

@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx");
        builder.serializerByType(ZonedDateTime.class, new ZonedDateTimeSerializer(formatter));
        builder.deserializerByType(ZonedDateTime.class, new ZonedDateTimeDeserializer(formatter));
    };
}

方案3:通过ModelMapper转换为字符串类型(备选)

如果允许POJOEntity的startTs字段为String类型,可在ModelMapper中添加转换器,直接将ZonedDateTime格式化为目标字符串:

import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class ModelMapperConfig {

    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        
        // 添加ZonedDateTime转String的转换器
        Converter<ZonedDateTime, String> dateToStringConverter = context -> {
            if (context.getSource() == null) {
                return null;
            }
            return context.getSource().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx"));
        };
        
        modelMapper.addConverter(dateToStringConverter);
        return modelMapper;
    }
}

此方案需将POJOEntity的startTs字段类型改为String,适合不需要对该字段做后续时间运算的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:50:28