MongoJack结合Kotlin使用时_id设置异常问题求助
Kotlin结合MongoJack插入MongoDB时的UnsupportedOperationException解决方法
问题描述
在Kotlin中使用MongoJack操作MongoDB时,已解决序列化/反序列化的基础问题,但插入文档时抛出UnsupportedOperationException,提示无法在TestDocument构造函数参数上调用setValue()。原因是MongoJack尝试自动生成_id时,无法操作Kotlin data class的主构造函数参数,添加空构造函数也无法解决,异常会充斥日志。
解决方案
1. 用@field:注解指定注解作用于字段
Kotlin data class的主构造函数参数默认会被Jackson识别为构造器参数,而非类字段。MongoJack自动生成_id后,尝试通过构造器参数的setValue()方法赋值,这会触发异常。通过给@ObjectId和@JsonProperty添加@field:前缀,让Jackson将注解应用于类字段,而非构造器参数,从而允许MongoJack直接修改字段值。
修改后的实体类代码:
data class TestDocument ( @field:ObjectId @field:JsonProperty("_id") var id: String? = null, @JsonProperty("name") var name: String, var date: Date = Date(), var decimal: BigDecimal = BigDecimal.valueOf(123.456) )
2. 确保Jackson ObjectMapper正确启用Kotlin模块
虽然jacksonObjectMapper()默认已包含Kotlin模块,但显式注册可避免版本兼容问题:
var jacksonObjectMapper = jacksonObjectMapper() .registerModule(KotlinModule.Builder().build()) MongoJackModule.configure(jacksonObjectMapper)
3. 手动生成_id(备选方案)
如果上述方法仍有问题,可以禁用MongoJack的自动生成_id功能,手动生成并赋值:
var testDoc = TestDocument(name="TestName").apply { id = ObjectId().toHexString() } MongoClientTest.testCol.drop() var insertOneResult = MongoClientTest.testCol.insertOne(testDoc)
为什么添加空构造函数无效?
Kotlin data class的空构造函数(即使添加)不会改变主构造函数参数的属性,MongoJack依然会尝试操作构造器参数而非类字段,因此无法解决问题。必须通过@field:注解引导Jackson识别字段,才能让MongoJack正确赋值_id。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

