Spring Joda LocalDateTime转换器:带时区Date存入MongoDB及通用配置
实现Spring Joda LocalDateTime转换器并配置MongoDB存储(含移除
_class字段) 嘿,我来帮你搞定这个Spring Data MongoDB结合Joda LocalDateTime的配置,完美适配你给出的mongoTemplate和mongoConverter Bean,同时还能去掉那个烦人的_class字段,一步到位!
1. 先确认依赖(没加的话补上)
确保项目里有Joda-Time和Spring Data MongoDB的依赖,以Maven为例:
<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.12.5</version> <!-- 用最新稳定版即可 --> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>3.4.10</version> <!-- 匹配你的Spring版本 --> </dependency>
2. 写自定义Joda LocalDateTime转换器
我们需要两个转换器:把LocalDateTime转成MongoDB支持的带UTC时区的Date(统一用UTC避免时区混乱),再把Mongo的Date转回LocalDateTime。
import org.joda.time.LocalDateTime import org.joda.time.DateTimeZone import org.springframework.core.convert.converter.Converter import java.util.Date // LocalDateTime -> 带UTC时区的Date class LocalDateTimeToDateConverter : Converter<LocalDateTime, Date> { override fun convert(source: LocalDateTime): Date { return source.toDateTime(DateTimeZone.UTC).toDate() } } // Date -> LocalDateTime(从UTC时区转回) class DateToLocalDateTimeConverter : Converter<Date, LocalDateTime> { override fun convert(source: Date): LocalDateTime { return LocalDateTime(source, DateTimeZone.UTC) } }
3. 配置MappingMongoConverter:注册转换器+移除_class字段
接下来整合你给出的Bean,同时完成转换器注册和_class字段的移除:
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.data.mongodb.MongoDatabaseFactory import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper import org.springframework.data.mongodb.core.convert.MappingMongoConverter import org.springframework.data.mongodb.core.convert.MongoCustomConversions import org.springframework.data.mongodb.core.mapping.MongoMappingContext import com.mongodb.client.MongoClient import com.mongodb.MongoClientURI @Configuration class MongoConfig { // 你原有的mongoDbFactory Bean @Bean open fun mongoDbFactory(mongoClient: MongoClient, mongoClientURI: MongoClientURI) = SimpleMongoDbFactory(mongoClient, mongoClientURI.database) // 注册自定义转换器 @Bean open fun mongoCustomConversions(): MongoCustomConversions { val converters = listOf( LocalDateTimeToDateConverter(), DateToLocalDateTimeConverter() ) return MongoCustomConversions(converters) } // 配置MappingMongoConverter:移除_class字段 + 关联自定义转换器 @Bean open fun mappingMongoConverter( mongoDbFactory: MongoDatabaseFactory, mongoMappingContext: MongoMappingContext, mongoCustomConversions: MongoCustomConversions ): MappingMongoConverter { val converter = MappingMongoConverter(mongoDbFactory, mongoMappingContext) // 移除自动生成的_class字段 converter.typeMapper = DefaultMongoTypeMapper(null) // 绑定自定义转换器 converter.setCustomConversions(mongoCustomConversions) return converter } // 你原有的mongoTemplate Bean,使用配置好的转换器 @Bean open fun mongoTemplate( mongoDbFactory: MongoDatabaseFactory, mongoConverter: MappingMongoConverter ): MongoTemplate { return MongoTemplate(mongoDbFactory, mongoConverter) } }
4. 验证使用
现在可以直接在实体类里用Joda的LocalDateTime字段了:
import org.joda.time.LocalDateTime import org.springframework.data.mongodb.core.mapping.Document @Document(collection = "test_data") data class TestEntity( val id: String, val createTime: LocalDateTime, val updateTime: LocalDateTime )
用mongoTemplate保存实体时,createTime和updateTime会被转成UTC时区的Date存进MongoDB;查询时又会自动转回LocalDateTime,全程无需手动处理时区转换。
关键细节说明
- 为什么用UTC时区? MongoDB的
Date本质是时间戳,统一用UTC存储可以避免不同环境下的时区偏移问题,是行业通用的最佳实践。 - 移除
_class字段的原理:通过给DefaultMongoTypeMapper传入null,直接禁用Spring Data自动写入类型标识字段的逻辑,让Mongo文档更简洁。 - 转换器必须通过
MongoCustomConversions注册:只有这样,Spring Data MongoDB才会识别并应用这些自定义转换规则。
内容的提问来源于stack exchange,提问作者user2105282
相关产品推荐
相关产品推荐

