JetBrains Exposed throwing an error when trying to access first row of select query
Asked Answered
H

1

7

When trying to fetch the first row from my transaction, I receive an error:

java.lang.IllegalStateException: No transaction in context.

My code looks like this:

fun loadPlayer(client: Client): PlayerLoadResult {
    var player = transaction {
        PlayerModel.select {
            PlayerModel.username eq client.loginUsername
        }
    }.firstOrNull() ?: return PlayerLoadResult.NEW_ACCOUNT

    // ...

    return PlayerLoadResult.LOAD_ACCOUNT
}

My PlayerModel looks like this:

object PlayerModel : Table("Players") {
    val id = integer("id").autoIncrement().primaryKey()
    val username = varchar("username", 60).uniqueIndex()
    val displayName = varchar("display_name", 60).uniqueIndex()
    val x = integer("position_x")
    val height = integer("position_y")
    val z = integer("position_z")
    val privilege = integer("privilege").default(1)
    val runEnergy = float("run_energy").default(100.toFloat())
    val displayMode = integer("display_mode").default(0)
    val hash = varchar("password_hash", 60)
    val xteaKeyOne = integer("xtea_one")
    val xteaKeyTwo = integer("xtea_two")
    val xteaKeyThree = integer("xtea_three")
    val xteaKeyFour = integer("xtea_four")
}

My full stack trace looks like this:

java.lang.IllegalStateException: No transaction in context.
    at org.jetbrains.exposed.sql.transactions.TransactionManager$Companion.current(TransactionApi.kt:89) ~[exposed-0.13.6.jar:?]
    at org.jetbrains.exposed.sql.Query.getTransaction(Query.kt:93) ~[exposed-0.13.6.jar:?]
    at org.jetbrains.exposed.sql.Query.flushEntities(Query.kt:299) ~[exposed-0.13.6.jar:?]
    at org.jetbrains.exposed.sql.Query.iterator(Query.kt:303) ~[exposed-0.13.6.jar:?]
    at kotlin.collections.CollectionsKt___CollectionsKt.firstOrNull(_Collections.kt:219) ~[kotlin-stdlib-1.3.21.jar:1.3.21-release-158 (1.3.21)]
    at gg.rsmod.plugins.service.sql.controllers.PlayerLoadController.loadPlayer(PlayerLoadController.kt:38) ~[plugins-0.0.4.jar:?]
    at gg.rsmod.plugins.service.sql.SQLService.loadClientData(SQLService.kt:104) ~[plugins-0.0.4.jar:?]
    at gg.rsmod.game.service.login.LoginWorker.run(LoginWorker.kt:28) [main/:?]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_211]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_211]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_211]

What seems to be the issue with fetching the first row? This query should only return a single row, not multiple.

How answered 22/4, 2019 at 15:42 Comment(2)
I've never used exposed. But the message says: "No transaction in context". And the call to firstOrNull(), which throws the exception, is outside of the transaction block. My logical deduction would be that it needs to be inside the transaction block.Fowlkes
That solved my issue! There documentation is so confusing sometimes. Thanks @JBNizetHow
H
8

For future viewers, this was resolved in the comments simply by moving the firstOrNull() inside the transaction blocks scope.

fun loadPlayer(client: Client): PlayerLoadResult {
    var player = transaction {
        PlayerModel.select {
            PlayerModel.username eq client.loginUsername
        }.firstOrNull() ?: return PlayerLoadResult.NEW_ACCOUNT
    }

    // ...

    return PlayerLoadResult.LOAD_ACCOUNT
}
How answered 5/1, 2022 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.