JDBI与Kotlin映射异常:根据用户名查询用户失败
解决JDBI映射Kotlin User数据类时的构造参数匹配异常
异常信息
Exception in thread "main" java.lang.IllegalArgumentException: Mapping Kotlin type User didn't find any columns matching required, non-default constructor parameters in result set at org.jdbi.v3.core.kotlin.KotlinMapper.specialize$lambda-3(KotlinMapper.kt:72) at java.base/java.util.Optional.orElseThrow(Optional.java:403) at org.jdbi.v3.core.kotlin.KotlinMapper.specialize(KotlinMapper.kt:71) at org.jdbi.v3.core.result.ResultSetResultIterator.<init>(ResultSetResultIterator.java:38) at org.jdbi.v3.core.result.ResultIterable.lambda$of$0(ResultIterable.java:57) at org.jdbi.v3.core.result.ResultIterable.one(ResultIterable.java:145) at JdbiUserRepository.getById$lambda-1(Main.kt:75) at org.jdbi.v3.core.Jdbi.withHandle(Jdbi.java:357) at JdbiUserRepository.getById(Main.kt:70) at MainKt.main(Main.kt:22) at MainKt.main(Main.kt)
核心问题
查询SQL语句select from users where username = :username未指定要查询的列,执行后返回的结果集不包含任何列数据。而Kotlin数据类User的构造函数需要username和password两个必填参数,JDBI无法找到对应的列值来构造对象,因此抛出映射异常。
解决方案
修改查询语句,明确指定要查询的username和password列,确保结果集包含构造User所需的全部字段:
修改后的查询方法
class JdbiUserRepository(private val jdbi: Jdbi) : UserRepository { override fun getById(username: String): User? = jdbi .withHandle<User?, Exception> { handle -> handle .createQuery("select username, password from users where username = :username") .bind("username", username) .mapTo<User>() .one() } }
补充说明
如果后续遇到数据库列名与数据类属性名不一致的情况,可以使用JDBI的@ColumnName注解指定映射关系,或者配置全局命名策略,但本次问题中列名与属性名完全匹配,只需修正SQL即可解决。
内容的提问来源于stack exchange,提问作者Sampeteq
相关产品推荐
相关产品推荐

