如何让MongoDB文档的_id为String而非ObjectId(Java驱动)
解决MongoDB将_id存储为String类型的问题
要让MongoDB文档的_id存为String而非默认的ObjectId,你需要抓住两个核心要点:正确标记主键字段和提供String类型的id值,具体操作如下:
1. 修改实体类,明确主键映射
把id字段用@BsonId注解标记(而非单纯的@BsonProperty("_id")),这个注解会明确告诉MongoDB驱动:该字段就是文档的_id主键。同时手动生成String类型的id值(比如用ObjectId转十六进制字符串,或者自定义UUID):
import org.bson.codecs.pojo.annotations.BsonId; import org.bson.types.ObjectId; public class Fruit { String name; @BsonId String id; // 构造方法中自动生成String类型id public Fruit(String name) { this.name = name; this.id = new ObjectId().toHexString(); } // getter、setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
2. 插入时确保id已赋值
如果不主动设置id的值,MongoDB驱动会默认生成ObjectId填充到_id字段,所以必须保证插入前id字段有String类型的有效值。上面的构造方法已经自动完成了id生成,插入代码无需改动:
// 原插入逻辑保持不变 Fruit newFruit = new Fruit("Apple"); collection.insertOne(newFruit);
可选:配置自动生成String类型id
如果不想手动写id生成逻辑,可以在PojoCodecProvider中配置String类型id的自动生成器,这样即使不手动设置id,驱动也会自动生成String值:
CodecProvider pojoCodecProvider = PojoCodecProvider.builder() .automatic(true) .register(Fruit.class) // 指定String类型id的生成规则 .idGenerator(String.class, () -> new ObjectId().toHexString()) .build(); // 后续CodecRegistry、MongoClient等代码保持不变 CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider)); MongoClient client = MongoClients.create("mongodb:...."); MongoDatabase database = client.getDatabase("myDbName").withCodecRegistry(pojoCodecRegistry); MongoCollection<Fruit> collection = database.getCollection("Fruits", Fruit.class);
问题根源说明
之前只加@BsonProperty("_id")无效,是因为这个注解仅完成字段与_id键的映射,但没有标记它为主键。MongoDB驱动会将其视为普通字段,同时自动生成ObjectId作为真正的_id主键,导致数据库中仍为ObjectId类型。而@BsonId会明确标记该字段为主键,驱动会直接使用该字段的String值,不再自动生成ObjectId。
内容的提问来源于stack exchange,提问作者James Work account
相关产品推荐
相关产品推荐

