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

使用MongoDB集合填充Java POJO类时获取值为null的问题

问题排查与解决

我尝试用MongoDB集合填充Java POJO类CsvRow,但调用doc.getVin()时返回null,相关代码如下:

类构造方法

MongoDatabase database;

MongoDbUtils() {
    String uri = "mongodb://localhost:27017/?maxPoolSize=20&w=majority";

    //This registry is required for your Mongo document to POJO conversion
    ConnectionString connectionString = new ConnectionString(uri);
    CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
    CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
    MongoClientSettings clientSettings = MongoClientSettings.builder()
            .applyConnectionString(connectionString)
            .codecRegistry(codecRegistry)
            .build();
    MongoClient mongoClient = MongoClients.create(clientSettings);
    database = mongoClient.getDatabase("StudyPriceDataTest");
}

从POJO检索数据的方法

public MongoCollection<CsvRow> RetriveAllDocumentsInCSVRows(String collectionName) {
    System.out.println(collectionName);
    MongoCollection<CsvRow> collection = database.getCollection(collectionName, CsvRow.class);
    List<CsvRow> csvRows = collection.find(new Document(), CsvRow.class).into(new ArrayList<CsvRow>());
    for(CsvRow doc:csvRows) {
        System.out.println("vinsds="+doc.getVin()); // <-- 这里返回null
    }
    return collection;
}

以下是几个最可能导致POJO字段映射为null的原因及解决办法:

1. POJO字段与MongoDB文档字段名不匹配

检查MongoDB集合内的文档,确认存储的字段名和CsvRow类中的vin字段完全一致(MongoDB字段名大小写敏感)。比如Mongo里存的是Vin或VIN,而POJO里是vin,就会映射失败。

  • 解决:要么修改Mongo文档的字段名和POJO一致,要么在POJO的vin字段上添加@BsonProperty注解指定对应Mongo字段名:
import org.bson.codecs.pojo.annotations.BsonProperty;

public class CsvRow {
    @BsonProperty("Vin") // 填写Mongo中实际的字段名
    private String vin;

    // 必须有对应的getter/setter
    public String getVin() { return vin; }
    public void setVin(String vin) { this.vin = vin; }
}

2. CsvRow类缺少无参构造方法

MongoDB的POJO映射机制要求类提供无参构造方法,否则无法通过反射实例化对象,所有字段都会是null。

  • 解决:给CsvRow添加无参构造:
public class CsvRow {
    private String vin;

    // 无参构造必须存在
    public CsvRow() {}

    // 带参构造可保留
    public CsvRow(String vin) {
        this.vin = vin;
    }

    // getter/setter
}

3. 字段没有对应的getter/setter方法

即使启用了automatic(true),私有字段仍需要public的getter和setter方法,供反射工具访问赋值。

  • 解决:确保CsvRow的vin字段有对应的getVin()和setVin(String vin)方法,且修饰符为public。

4. 命名策略不匹配

如果Mongo文档使用下划线命名(比如vin_code),而POJO用驼峰命名(vinCode),默认映射策略会无法匹配。

  • 解决:配置PojoCodecProvider时指定命名策略:
CodecRegistry pojoCodecRegistry = fromProviders(
    PojoCodecProvider.builder()
        .automatic(true)
        .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE) // 适配下划线转驼峰
        .build()
);

额外检查

  • 确认MongoDB集合中确实存在vin字段的有效值,不是文档本身就没有该字段或值为null;
  • 检查MongoDB驱动版本是否与POJO映射要求兼容,建议使用最新稳定版的mongodb-driver-sync和mongodb-driver-core。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:20:21