Hello, may I ask a question? I would like to enfor...
# komapper
y
Hello, may I ask a question? I would like to enforce the use of transactions. Is there a way to do that? So far, I have been able to run the following code without any problems.
Copy code
fun main() {
    val db = JdbcDatabase("jdbc:h2:mem:example;DB_CLOSE_DELAY=-1")

    val a = Meta.address

    db.runQuery {
        QueryDsl.create(a)
    }

    val newAddress = db.runQuery {
        QueryDsl.insert(a).single(Address(street = "street A"))
    }

    val address1 = db.runQuery {
        QueryDsl.from(a).where { a.id eq newAddress.id }.first()
    }

    println("address1 = $address1")
}
However, I want it to throw an exception at
db.runQuery
.
Oh, I understand. It seems that it was because autocommit was turned on. I added the
AUTOCOMMIT=OFF
flag and now the exception is raised.
Copy code
JdbcDatabase("jdbc:h2:mem:example;DB_CLOSE_DELAY=-1;AUTOCOMMIT=OFF")
However, the exceptions may be a bit confusing...
Copy code
Exception in thread "main" java.util.NoSuchElementException: Expected at least one element
        at kotlinx.coroutines.flow.FlowKt__ReduceKt.first(Reduce.kt:96)
        at kotlinx.coroutines.flow.FlowKt.first(Unknown Source)
        at org.komapper.core.dsl.query.QueryUtilityCompositionKt$first$1.invokeSuspend(QueryUtilityComposition.kt:46)
        at org.komapper.core.dsl.query.QueryUtilityCompositionKt$first$1.invoke(QueryUtilityComposition.kt)
        at org.komapper.core.dsl.query.QueryUtilityCompositionKt$first$1.invoke(QueryUtilityComposition.kt)
        at org.komapper.jdbc.DefaultJdbcExecutor$executeQuery$2$1$1$1$1.invokeSuspend(JdbcExecutor.kt:89)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
        at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
        at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
        at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
        at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
        at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
        at org.komapper.jdbc.DefaultJdbcExecutor$executeQuery$2$1.invoke(JdbcExecutor.kt:88)
        at org.komapper.jdbc.DefaultJdbcExecutor$executeQuery$2$1.invoke(JdbcExecutor.kt:77)
        at org.komapper.jdbc.JdbcSession$DefaultImpls.useConnection(JdbcSession.kt:34)
        at org.komapper.tx.jdbc.JdbcTransactionSession.useConnection(JdbcTransactionSession.kt:14)
        at org.komapper.jdbc.DefaultJdbcExecutor$executeQuery$2.invoke(JdbcExecutor.kt:77)
        at org.komapper.jdbc.DefaultJdbcExecutor.withExceptionTranslator(JdbcExecutor.kt:179)
        at org.komapper.jdbc.DefaultJdbcExecutor.executeQuery(JdbcExecutor.kt:74)
        at org.komapper.jdbc.dsl.runner.JdbcSelectRunner.run(JdbcSelectRunner.kt:28)
        at org.komapper.jdbc.JdbcDatabaseImpl.runQuery(JdbcDatabase.kt:72)
        at org.komapper.jdbc.JdbcDatabaseImpl.runQuery(JdbcDatabase.kt:77)
Hmmm? The exception is happening in the third
db.runQuery
, so
create table
and
inset
are succeeding? I’m a bit confused.
t
I would like to enforce the use of transactions. Is there a way to do that?
However, I want it to throw an exception at
db.runQuery
.
Try the following code:
Copy code
val original = JdbcDatabase("jdbc:h2:mem:example;DB_CLOSE_DELAY=-1")
val db = object : JdbcDatabase by original {
    override fun <T> runQuery(query: Query<T>): T {
        if (config.session.getConnection().autoCommit) error("no transaction")
        return original.runQuery(query)
    }

    override fun <T> runQuery(block: QueryScope.() -> Query<T>): T {
        if (config.session.getConnection().autoCommit) error("no transaction")
        return original.runQuery(block)
    }
}
y
@Toshihiro Nakamura Thanks for the advice. It worked as expected. I see that it is a combination of Anonymous Objects and Delegation. That will be helpful.