Search code examples
kotlinprimary-keypsqlkotlin-exposed

Extending IntIdTable in Kotlin Exposed PSQL does not inherit primary key


Problem Summary

I'm trying to create an abstract class UserTable that inherits the IntIdTable of the Kotlin Exposed framework as such:

abstract class UserTable : IntIdTable() {
    val userId = integer("userId").references(SystemUsers.id)
    val created = timestamp("created").defaultExpression(CurrentTimestamp())
    val updated = timestamp("updated").defaultExpression(CurrentTimestamp())
}

The idea is that I can then extend this UserTable with tables that contain rows specific to a system user. Something such as table ContantInformation:

object ContactInformation: UserTable() {
  val name = varchar("name", length = 63)
  val email = varchar("email", length = 127)
}

When running the application, the tables get created with integer IDs, but the primary key, and thereby the unique constraint, is missing from table ContactInformation. This causes the issue that when I try to reference the contact information in another table, such as:

object Users : IntIdTable() {
    val contactInformationId = integer("contactInformationId").references(ContactInformation.id)
}

I get the error

ERROR: there is no unique constraint matching given keys for referenced table "ContactInformation"

The primary key is final in table IntIdTable as well, so I cannot override it. Is there a way to inherit the primary key, or another way to add the a unique modifier to the table ContactInformation?

Versions

kotlin=2.0.0
postgresql=42.7.3
exposed=0.41.1


Solution

  • I found that re-writing from IntIdTable to UUIDTable solved the issue. However, I had to drop and re-create all tables.

    abstract class UserTable : UUIDTable() {
        val userId = integer("userId").references(SystemUsers.id)
        val created = timestamp("created").defaultExpression(CurrentTimestamp())
        val updated = timestamp("updated").defaultExpression(CurrentTimestamp())
    }
    
    object Users : IntIdTable() {
        val contactInformationId = uuid("contactInformationId").references(ContactInformation.id)
    }