Helene Ballet
03/27/2025, 4:55 PMcreationDate
field for instance, or a metadata
field referencing a different table).
I am using a DAO approach and I was hopping to do something like :
abstract class TableWithMetadata(name: String) : LongIdTable(name) {
val creationDate = datetime("creation_date")
}
object DataTable : TableWithMetadata("data") {
val title = varchar("title", length = MAX_STRING_LENGTH)
}
with
abstract class DbDtoWithMetadata<T: TableWithMetadata>(id: EntityID<Long>) : LongEntity(id) {
var creationDate by T.creationDate
}
class DataDbDto(id: EntityID<Long>) : DbDtoWithMetadata<DataTable>(id) {
companion object : LongEntityClass<DataDbDto>(DataTable)
var title by DataTable.title
}
and call it like that :
transaction {
DataDbDto.new {
creationDate = LocalDateTime.now() // Or find a more generic way, so it applies automagically to all DbDto extending DbDtoWithMetadata
title = data.title
}
}
but this doesn't work due to a compilation error in DbDtoWithMetadata
: Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left-hand side of a dot.
Do you have a workaround or a better way to handle this use case ?Chantal Loncle
03/31/2025, 2:37 PMabstract class DbDtoWithMetadata(
id: EntityID<Long>,
table: TableWithMetadata
) : LongEntity(id) {
var creationDate by table.creationDate
}
class DataDbDto(id: EntityID<Long>) : DbDtoWithMetadata(id, DataTable) { }
For the automatic creationDate
, there are some options depending on what you need or prefer:
• Override `new()`:
companion object : LongEntityClass<DataDbDto>(DataTable) {
override fun new(id: Long?, init: DataDbDto.() -> Unit): DataDbDto {
return super.new(id) {
creationDate = LocalDateTime.now()
init()
}
}
}
• Register the column with the default initializing function:
datetime("creation_date").clientDefault { LocalDateTime.now() }
Here is a related section in the docs that shows an example of one way to set up abstract base entities.Helene Ballet
04/24/2025, 9:52 AMabstract class DbDtoWithMetadata
having TableWithMetadata
as a parameter is exactly what I needed 🙏
Though I like the idea of overriding new()
, I didn't want to do it for each implementation of DbDtoWithMetadata
.
I ended up going with a solution I found in the doc you linked, using defaultExpression()
:
abstract class TableWithMetadata(name: String) : LongIdTable(name) {
val creationDate = datetime("creation_date").defaultExpression(CurrentDateTime)
}
Helene Ballet
04/24/2025, 9:54 AM