jOOQ 3.15.1的ad-hoc转换API是否支持Kotlin?遇到编译问题如何解决?
jOOQ 3.15 Kotlin类型适配问题解决方案
jOOQ 3.15.1版本的核心mapping函数是为Java设计的,未原生适配Kotlin的类型系统与函数引用规则,你遇到的两个问题均由此导致。
问题成因
- 位置[1]报错是因为Kotlin构造器引用
::Actor的参数默认按不可空类型String推导,而jOOQ返回的字段是可空的String?,Java SAM转换逻辑无法匹配可空与不可空的参数类型差异,所以提示类型不匹配。 - 位置[2]报错是因为jOOQ的
mapping方法存在最多22个参数的重载实现,Kotlin类型推断机制无法自动匹配到和Film构造器参数数量对应的重载版本。
可行解决方案
方案1:引入jOOQ官方Kotlin扩展模块(推荐)
jOOQ官方提供了org.jooq:jooq-kotlin扩展模块,专门适配Kotlin场景下的mapping调用,完美解决可空类型匹配、重载自动选择问题,无需修改原有数据类和业务逻辑。
导入扩展后修改后的代码示例:
// 导入Kotlin专属mapping扩展 import org.jooq.kotlin.mapping // 原有数据类无需修改 data class Actor(val firstName: String?, val lastName: String?) data class Film(val title: String?, val actors: List<Actor>, val categories: List<String>) ... val future = dsl.select( FILM.TITLE, multiset( select( FILM_ACTOR.actor().FIRST_NAME, FILM_ACTOR.actor().LAST_NAME ) .from(FILM_ACTOR) .where(FILM_ACTOR.FILM_ID.eq(FILM.FILM_ID)) ).`as`("actors").convertFrom { it.map( mapping(::Actor) ) }, multiset( select(FILM_CATEGORY.category().NAME) .from(FILM_CATEGORY) .where(FILM_CATEGORY.FILM_ID.eq(FILM.FILM_ID)) ).`as`("categories").convertFrom { it.map { r -> r.getValue(0) } } ) .from(FILM) .orderBy(FILM.TITLE) .fetchAsync() val result = future.await().map( mapping(::Film) )
方案2:无额外依赖的临时适配
如果暂时无法引入jooq-kotlin依赖,可以用显式声明参数类型的lambda代替构造器引用,手动绕过类型检查:
- 位置[1]修改为:
mapping { firstName: String?, lastName: String? -> Actor(firstName, lastName) } - 位置[2]修改为:
mapping { title: String?, actors: List<Actor>, categories: List<String> -> Film(title, actors, categories) }
内容的提问来源于stack exchange,提问作者David Bullock
相关产品推荐
相关产品推荐

