MongoDB嵌入式文档Review的_id存为ObjectId,查询需显示为String的问题
解决方案:实现ObjectId存储、String展示与查询兼容
我之前也碰到过类似的问题,嵌入式文档的ObjectId处理确实容易踩坑,给你两个实用的解决方案:
方法一:使用Jackson序列化/反序列化注解
这种方法适合用Jackson处理JSON序列化的场景,直接在_id字段上添加注解,实现双向转换:
import org.bson.types.ObjectId; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.databind.deser.std.StringDeserializer; public class Review { @Id @JsonSerialize(using = ToStringSerializer.class) @JsonDeserialize(using = StringDeserializer.class) private ObjectId _id = new ObjectId(); private String userid; private String username; private String reviewstring; // 必须编写Getter和Setter,Jackson需要通过它们访问字段 public ObjectId getId() { return _id; } public void setId(ObjectId id) { this._id = id; } // 可选:额外添加一个String类型的getter,方便前端直接获取字符串ID public String getIdAsString() { return _id.toHexString(); } }
这样做的效果:
- 存储到MongoDB时,
_id依然保持ObjectId类型,不改变数据库存储结构 - 查询返回给前端时,
_id会被序列化为十六进制字符串,不会显示ObjectId的内部字段(比如timestamp、machineIdentifier) - 前端传String类型的ID查询时,Jackson会自动把字符串反序列化为ObjectId,解决查询返回null的问题
方法二:自定义MongoDB全局转换器
如果项目依赖Spring Data MongoDB的转换机制,可以自定义全局转换器,让所有ObjectId字段自动处理:
1. 编写ObjectId转String的读取转换器
import org.bson.types.ObjectId; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; @ReadingConverter public class ObjectIdToStringConverter implements Converter<ObjectId, String> { @Override public String convert(ObjectId source) { return source != null ? source.toHexString() : null; } }
2. 编写String转ObjectId的写入转换器
import org.bson.types.ObjectId; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.WritingConverter; @WritingConverter public class StringToObjectIdConverter implements Converter<String, ObjectId> { @Override public ObjectId convert(String source) { return source != null && ObjectId.isValid(source) ? new ObjectId(source) : null; } }
3. 注册转换器到MongoDB配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import java.util.Arrays; @Configuration public class MongoConfig { @Bean public MongoCustomConversions mongoCustomConversions() { return new MongoCustomConversions(Arrays.asList( new ObjectIdToStringConverter(), new StringToObjectIdConverter() )); } }
这种方法是全局生效的,所有实体类中的ObjectId字段都会自动在存储时保持ObjectId,查询时转为String,同时支持用String类型的ID进行查询。
额外注意点
- 若使用Spring Data MongoDB的Repository查询,比如
findReviewById(String id),转换器会自动把String转成ObjectId,能正确匹配数据库中的数据 - 嵌入式文档场景下,这两种方法都能生效,Spring Data MongoDB和Jackson都会递归处理嵌套的实体类
内容的提问来源于stack exchange,提问作者Azyar
相关产品推荐
相关产品推荐

