MongoDB Java驱动如何配置复合_id字段顺序避免生成重复文档?
解决方案
方案1:使用@BsonPropertyOrder注解直接指定字段顺序(最简便)
MongoDB Java驱动原生提供@BsonPropertyOrder注解,功能完全等价于Jackson的@JsonPropertyOrder,直接标注在你的自定义复合ID类上即可强制指定序列化后的字段顺序:
import org.bson.codecs.pojo.annotations.BsonProperty; import org.bson.codecs.pojo.annotations.BsonPropertyOrder; // 明确指定b在前、a在后的序列化顺序 @BsonPropertyOrder({"b", "a"}) public class CompositeId { @BsonProperty("b") private String b; @BsonProperty("a") private String a; // 省略构造方法、getter、setter }
该配置优先级高于全局配置,不需要调整其他驱动参数即可生效。
方案2:全局配置MongoDB驱动保留字段声明顺序
如果需要对所有POJO生效,保留类中字段的声明顺序,可以修改PojoCodecProvider的配置:
普通Java环境配置
import org.bson.codecs.configuration.CodecRegistries; import org.bson.codecs.configuration.CodecRegistry; import org.bson.codecs.pojo.PojoCodecProvider; import com.mongodb.MongoClientSettings; PojoCodecProvider pojoCodecProvider = PojoCodecProvider.builder() .automatic(true) // 核心配置:保留类字段的声明顺序,不再按字母序重排 .preserveDocumentFieldOrder(true) .build(); CodecRegistry codecRegistry = CodecRegistries.fromRegistries( MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider) ); // 构造MongoClient时传入该CodecRegistry即可
Quarkus 1.1.1环境配置
由于Quarkus 1.1.1版本没有提供对应的配置项,可通过CDI生产者自定义MongoClientSettings实现全局配置:
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import org.bson.codecs.configuration.CodecRegistries; import org.bson.codecs.pojo.PojoCodecProvider; import com.mongodb.MongoClientSettings; @ApplicationScoped public class CustomMongoSettingsProducer { @Produces public MongoClientSettings produceMongoClientSettings() { PojoCodecProvider pojoCodecProvider = PojoCodecProvider.builder() .automatic(true) .preserveDocumentFieldOrder(true) .build(); var codecRegistry = CodecRegistries.fromRegistries( MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider) ); return MongoClientSettings.builder() .codecRegistry(codecRegistry) // 其余连接参数会自动从application.properties中读取 .build(); } }
完成以上任意一种配置后,Java侧存储的复合_id字段顺序会和预期一致,和pymongo侧用OrderedDict构造的_id顺序匹配,不会再生成重复文档。
内容的提问来源于stack exchange,提问作者Ori Dar
相关产品推荐
相关产品推荐

