如何让Java MongoDB Driver序列化实体时不调用Getter存储原值
解决MongoDB Java Driver序列化时取字段实际值而非getter返回值的问题
问题原因
MongoDB Java Driver的POJO默认序列化策略是通过getter方法获取字段值,所以你的getVal()方法在val为null时返回"someValue",导致数据库中存的是这个处理后的值,而非字段实际的null。
下面提供两种简单的解决思路:
方案一:分离业务逻辑与序列化逻辑
把原来getVal()里的默认值逻辑移到专门的业务方法中,让getVal()直接返回字段的实际值,供序列化使用:
public class TestJavaMongoDriverEntityMDO { @BsonProperty("_id") private ObjectId id; @BsonProperty("val") private String val; // 构造方法不变 public TestJavaMongoDriverEntityMDO() { this.val = null; } public TestJavaMongoDriverEntityMDO(String val) { this.val = val; } // 序列化用的getter,直接返回字段实际值 public String getVal() { return val; } // 新增业务场景用的方法,保留原来的默认值逻辑 public String getDisplayVal() { if (val == null) { return "someValue"; } return val; } // 其他setter和getter不变 public void setVal(String val) { this.val = val; } public ObjectId getId() { return id; } public void setId(ObjectId id) { this.id = id; } }
这样序列化时Driver会读取val字段的真实值(null)存入数据库,业务代码里用getDisplayVal()获取带默认值的结果即可。
方案二:配置POJO映射使用字段访问模式
如果不想修改现有getter方法,可以在创建MongoClient时,指定POJO的属性访问策略为直接读取字段,绕过getter方法:
// 构建POJO代码提供者,指定字段访问策略 CodecRegistry pojoCodecRegistry = CodecRegistries.fromProviders( PojoCodecProvider.builder() .automatic(true) .register(TestJavaMongoDriverEntityMDO.class) .propertyAccessStrategy(PropertyAccessStrategy.FIELD) .build() ); // 合并默认CodecRegistry和自定义的POJO CodecRegistry CodecRegistry codecRegistry = CodecRegistries.fromRegistries( MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry ); // 创建MongoClient时使用配置好的CodecRegistry MongoClientSettings settings = MongoClientSettings.builder() .codecRegistry(codecRegistry) .build(); MongoClient mongoClient = MongoClients.create(settings);
配置完成后,Driver会直接反射读取实体类的val字段值,不再调用getVal()方法,自然就能把实际的null存入数据库。
内容的提问来源于stack exchange,提问作者ondra
相关产品推荐
相关产品推荐

