Kotlin结合JDBI使用时抛出NoSuchMethodException异常如何解决?
问题根因
- 你当前调用的
mapToBean()是面向Java Bean规范的映射逻辑,要求目标类必须提供公共无参构造方法和属性对应的setter方法,而你定义的Kotlin data class默认仅生成带所有参数的构造方法,无论属性用val还是var都不会自动生成无参构造,因此触发找不到<init>()的异常。 - 你仅引入了
jdbi3-kotlin-sqlobject依赖,缺少JDBI官方针对Kotlin类的核心映射依赖jdbi3-kotlin,无法使用适配Kotlin特性的映射能力。
可行解决方案(推荐优先选方案1,符合Kotlin开发习惯)
方案1:使用JDBI Kotlin原生映射(无需无参构造、无需修改原有data class)
- 在
build.gradle依赖中新增Kotlin核心适配依赖,版本与现有jdbi依赖保持一致:
implementation 'org.jdbi:jdbi3-kotlin:3.23.0'
- 初始化Jdbi实例时注册Kotlin插件:
val jdbi = Jdbi.create(dataSource).apply { installPlugin(KotlinPlugin()) installPlugin(KotlinSqlObjectPlugin()) // 配合你已引入的sqlobject依赖使用 }
- 将查询代码中的
mapToBean()替换为Kotlin适配的mapTo():
val users = jdbi.withHandleUnchecked { it .createQuery("select id, name from users") .mapTo(User::class.java) .list() }
该方案下你原本的data class User(val id: Int, val name: String)不需要做任何修改,完全兼容不可变属性的data class。
方案2:保留mapToBean()调用,适配Java Bean规范
如果必须使用mapToBean(),只需要给data class的所有构造参数添加默认值,Kotlin编译器会自动生成无参构造方法:
data class User(val id: Int = 0, val name: String = "")
注意该方案不需要把属性改成var,只要有默认值即可生成无参构造,属性可保留不可变特性。
内容的提问来源于stack exchange,提问作者nilTheDev
相关产品推荐
相关产品推荐

