Skip to content

Commit

Permalink
EXPOSED-495 Unable to create new Entity when server-side default valu…
Browse files Browse the repository at this point in the history
…e is used for a Column of type OffsetDateTime (TIMESTAMP WITH TIME ZONE)
  • Loading branch information
obabichevjb committed Sep 17, 2024
1 parent 5adca09 commit 69666ce
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ open class InsertStatement<Key : Any>(
if (firstAutoIncColumn != null || returnedColumns.isNotEmpty()) {
while (rs?.next() == true) {
try {
val returnedValues = returnedColumns.associateTo(mutableMapOf()) { it.first to rs.getObject(it.second) }
val returnedValues = returnedColumns.associateTo(mutableMapOf()) {
it.first to it.first.columnType.readObject(rs, it.second)
}
if (returnedValues.isEmpty() && firstAutoIncColumn != null) {
returnedValues[firstAutoIncColumn] = rs.getObject(1)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jetbrains.exposed

import org.jetbrains.exposed.dao.Entity
import org.jetbrains.exposed.dao.EntityClass
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.flushCache
Expand Down Expand Up @@ -32,6 +34,10 @@ import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue


private val dbTimestampNow: CustomFunction<OffsetDateTime>
get() = object : CustomFunction<OffsetDateTime>("now", JavaOffsetDateTimeColumnType()) {}

class DefaultsTest : DatabaseTestsBase() {
object TableWithDBDefault : IntIdTable() {
var cIndex = 0
Expand Down Expand Up @@ -555,4 +561,38 @@ class DefaultsTest : DatabaseTestsBase() {
assertEquals(0, statements.size)
}
}

object DefaultTimestampTable : IntIdTable("test_table") {
val timestamp: Column<OffsetDateTime> =
timestampWithTimeZone("timestamp").defaultExpression(dbTimestampNow)
}

class DefaultTimestampEntity(id: EntityID<Int>) : Entity<Int>(id) {
companion object : EntityClass<Int, DefaultTimestampEntity>(DefaultTimestampTable)

var timestamp: OffsetDateTime by DefaultTimestampTable.timestamp
}

@Test
fun testCustomDefaultTimestampFunctionWithEntity() {
withTables(excludeSettings = TestDB.ALL - TestDB.ALL_POSTGRES - TestDB.MYSQL_V8 - TestDB.ALL_H2, DefaultTimestampTable) {
val entity = DefaultTimestampEntity.new {}

val timestamp = DefaultTimestampTable.selectAll().first()[DefaultTimestampTable.timestamp]

assertEquals(timestamp, entity.timestamp)
}
}

@Test
fun testCustomDefaultTimestampFunctionWithInsertStatement() {
// Only Postgres allows to get timestamp values directly from the insert statement due to implicit 'returning *'
withTables(excludeSettings = TestDB.ALL - TestDB.ALL_POSTGRES, DefaultTimestampTable) {
val entity = DefaultTimestampTable.insert { }

val timestamp = DefaultTimestampTable.selectAll().first()[DefaultTimestampTable.timestamp]

assertEquals(timestamp, entity[DefaultTimestampTable.timestamp])
}
}
}

0 comments on commit 69666ce

Please sign in to comment.