Java转Kotlin时jOOQ结合SimpleFlatMapper映射数据类提示无可用构造函数报错
问题触发原因
该报错由SimpleFlatMapper(SFM)的构造函数解析逻辑和Kotlin数据类的特性不匹配导致,核心原因有两个:
- 即使你给数据类属性加了默认值、引入了no-args插件,Kotlin默认生成的无参构造要么是JVM层面的合成构造(SFM的反射逻辑默认无法识别),要么是no-args插件配置未生效,没有给目标实体类生成公开可访问的无参构造。
Doc类构造参数中包含了关联集合属性questions,SFM匹配构造函数时会将所有构造参数和查询返回的字段做映射,但你的查询没有返回对应questions的字段,因此无法匹配到可用的构造函数。
解决方法
以下三个方案任选其一即可:
方案1:调整SFM Mapper配置(最便捷)
初始化SelectQueryMapperFactory时禁用构造函数解析,强制SFM走字段/setter注入,适配Kotlin数据类的属性赋值逻辑:
private val docMapper = SelectQueryMapperFactory .newInstance() .constructorResolver(ConstructorResolver.NO_CONSTRUCTOR) .newMapper(Doc::class.java)
方案2:正确配置no-args插件
确保no-args插件为实体类生成公开无参构造,以Gradle Kotlin DSL配置为例:
- 引入并配置no-args插件
plugins { kotlin("jvm") version "1.5.31" kotlin("plugin.noarg") version "1.5.31" } noArg { // 自定义注解标记需要生成无参构造的类 annotation("com.test.common.NoArg") invokeInitializers = true }
- 自定义
@NoArg注解,并给Doc、Question类加上该注解:
@Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) annotation class NoArg @NoArg data class Doc( var docId: Int? = null, val title: String? = "", val description: String? = "", var questions: List<Question?>? = null, ) @NoArg data class Question( var questionId: Int? = null, var docId: Int? = null, var question: String? = "", var answer: String? = "" )
方案3:调整数据类结构
把集合关联属性移出构造函数,让SFM可以匹配到仅包含数据库字段的构造参数:
data class Doc( var docId: Int? = null, val title: String? = "", val description: String? = "", ) { var questions: List<Question?>? = null }
内容的提问来源于stack exchange,提问作者user10993231
相关产品推荐
相关产品推荐

