javadatabasekotlingradlejdbi

JDBI and Kotlin mapping


I'm getting mapping exception when trying to fetch user by its username. // I dont know why Stack Overflow requires so many non-code descriptions......................................................................................

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)

User class:

data class User(val username: String, val password: String)

Method:

class JdbiUserRepository(private val jdbi: Jdbi) : UserRepository {

override fun getById(username: String): User? = jdbi
    .withHandle<User?, Exception> { handle -> handle
        .createQuery("select from users where username = :username")
        .bind("username", username)
        .mapTo<User>()
        .one()
    }
}

Gradle:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.7.10"
application
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
mavenCentral()
}

dependencies {
testImplementation(kotlin("test"))
implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.10")
implementation("org.jdbi:jdbi3-core:3.32.0")
implementation("com.h2database:h2:1.4.200")
implementation("org.jdbi:jdbi3-kotlin:3.32.0")
implementation("org.jdbi:jdbi3-kotlin-sqlobject:3.32.0")
}

tasks.test {
useJUnitPlatform()
}

tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}

application {
mainClass.set("MainKt")
}

Users table (sql script):

create table users (
username varchar primary key,
password varchar
)

Solution

  • I believe your query is incorrect:

    .createQuery("select from users where username = :username")
    

    should be

    .createQuery("select username, password from users where username = :username")
    

    Documentation