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

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)

  1. 在build.gradle依赖中新增Kotlin核心适配依赖,版本与现有jdbi依赖保持一致:
implementation 'org.jdbi:jdbi3-kotlin:3.23.0'
  1. 初始化Jdbi实例时注册Kotlin插件:
val jdbi = Jdbi.create(dataSource).apply {
    installPlugin(KotlinPlugin())
    installPlugin(KotlinSqlObjectPlugin()) // 配合你已引入的sqlobject依赖使用
}
  1. 将查询代码中的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:24:01