Spring Data MongoDB 3.x:如何恢复2.x的实体默认值映射旧行为?
问题描述
MongoDB集合中存在如下文档:
{_id: xxx, my_field: null}
对应的Spring Data MongoDB实体代码(Kotlin)如下:
@Document class Test () { @Id open var id: ObjectId = ObjectId() @Field("my_field") var myField: Boolean = false }
该代码在Spring 2.x版本可正常运行,但升级至Spring 3.x后触发如下NullPointerException:
java.lang.NullPointerException: Cannot invoke "java.lang.Number.intValue()" because the return value of "sun.invoke.util.ValueConversions.primitiveConversion(sun.invoke.util.Wrapper, Object, boolean)" is null at java.base/sun.invoke.util.ValueConversions.unboxBoolean(ValueConversions.java:108) ~[na:na]
请问能否在不更新集合中现有文档的情况下,恢复旧版本的兼容行为?
解决方案
可以通过以下几种方式实现兼容,无需修改集合中的文档:
1. 改用包装类型替代原始布尔类型
将实体中的原始类型Boolean改为可空的包装类型Boolean?,这样当MongoDB返回null时,字段会被赋值为null,避免触发拆箱时的空指针异常。如果需要保持默认值为false,可以在实体初始化或业务逻辑中处理:
@Document class Test () { @Id open var id: ObjectId = ObjectId() @Field("my_field") var myField: Boolean? = false // 改为可空包装类型 }
2. 自定义字段转换器
实现一个自定义转换器,将null值自动转换为false,注册到MongoDB的映射配置中,模拟Spring 2.x的转换逻辑:
@Component class NullToBooleanConverter : Converter<Any?, Boolean> { override fun convert(source: Any?): Boolean { return source?.let { it as Boolean } ?: false } }
然后在配置类中注册该转换器:
@Configuration class MongoConfig : AbstractMongoClientConfiguration() { override fun getDatabaseName(): String { return "你的数据库名称" } override fun configureConverters(adapter: MongoConverterConfigurationAdapter) { adapter.registerConverter(NullToBooleanConverter()) super.configureConverters(adapter) } }
这样读取my_field为null的文档时,会自动将值转为false,和旧版本行为一致。
3. 配置Spring Data MongoDB的空值转换属性
在Spring Boot配置文件(application.yml或application.properties)中添加以下配置,开启空值到原始类型的默认转换:
spring: data: mongodb: mapping: convert-null-values: true
该配置会让框架自动将null转换为对应原始类型的默认值(布尔类型默认是false),无需修改实体代码。注意需确认使用的Spring Data MongoDB 3.x版本支持该配置项。
内容的提问来源于stack exchange,提问作者Hett
相关产品推荐
相关产品推荐

