Hi, I'm using Exposed for the first time to build an application to view and edit data on a database.
To do this I use DAO and I keep data objects saved after retrieving them from the database.
When I try to update an object with a wrong value I expect to receive an exception I can handle, but the transaction terminates with no errors and the value on the local object remains the wrong one. If I try to refetch the object from the database I get the old value (of course, the database didn't allow writing a wrong value).
Here's a simple example:
var step = transaction { Step.all().first() }
println("Number before update ${step.number}")
for (i in 1..2) {
try {
transaction {
addLogger(StdOutSqlLogger)
step.number = -1
}
} catch (e: SQLException) {
println("didnt work")
}
}
println("Number after update ${step.number}")
step = transaction { Step.all().first() }
println("Number after refetch ${step.number}")
and the output is
Number before update 2
SQL: SELECT step.id, step.adventure, step."number", step."text", step.loot FROM step WHERE step.id = 2
SQL: UPDATE step SET "number"=-1 WHERE id = 2
SQL: SELECT step.id, step.adventure, step."number", step."text", step.loot FROM step WHERE step.id = 2
SQL: SELECT step.id, step.adventure, step."number", step."text", step.loot FROM step WHERE step.id = 2
Number after update -1
Number after refetch 2
The Step class is declared as follows
object Steps : AdventureTable("STEP") { // AdventureTable just declares the adventure field
val number = integer("number").check { it greaterEq Step.MIN_NUMBER }
val text = text("text")
init {
uniqueIndex(adventure, number)
}
}
class Step(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<Step>(Steps) {
const val MIN_NUMBER = 1
}
var number by Steps.number
var text by Steps.text
var adventure by Adventure referencedOn Steps.adventure
}
EDIT: fixed table declaration
What database do you use?
I'm using PostgreSQL version 9.6.17.
Looking deeper with a debugger, seems that the following events occur:
commit() on the transactionrepetitionAttempts is not reached yet (looking at the run method of ThreadLocalTransactionManager) it is ignored before retryingThis is what I understood looking at the code and the execution. Maybe the only problem is that the entityCache is flushed before being sure the transaction was successful..? Just guessing
Most helpful comment
I'm using PostgreSQL version 9.6.17.
Looking deeper with a debugger, seems that the following events occur:
commit()on the transactionrepetitionAttemptsis not reached yet (looking at therunmethod ofThreadLocalTransactionManager) it is ignored before retryingThis is what I understood looking at the code and the execution. Maybe the only problem is that the entityCache is flushed before being sure the transaction was successful..? Just guessing