You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Kotlin Exposed建立表关联时PostgreSQL唯一约束错误排查

问题:Exposed ORM建立一对一关联时出现唯一约束匹配错误

尝试使用JetBrains的Exposed ORM库在Kotlin中建立Users和RefreshTokens两张表的一对一关联,定义的表结构如下:

object Users : IdTable<UUID>() {
    override val id = uuid("user_id").entityId()
    val name = varchar("name", 255)
    val email = varchar("email", 255).uniqueIndex()
    val passwordHash = varchar("password_hash", 60)
}

object RefreshTokens: IdTable<UUID>() {
    override val id = uuid("refresh_token_id").entityId()
    val userId = reference("user_id", Users).uniqueIndex()
    val token = varchar("token", 255)
    val expiresAt = datetime("expires_at")
}

连接PostgreSQL数据库并创建表结构的函数:

fun Application.configureDatabase() {
    Database.connect(
        "jdbc:postgresql://localhost:5432/ktordb",
        driver = "org.postgresql.Driver",
        user = "root",
        password = "1234"
    )

    transaction {
        SchemaUtils.create(Users)
        SchemaUtils.create(RefreshTokens)
    }
}

运行后出现错误:

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

已尝试将Users表的id列设置为主键和唯一约束,但错误仍然存在,请问哪里操作出错了?


解决方案

问题根源

你在RefreshTokens中使用reference("user_id", Users)时,Exposed自动推断关联列出现偏差,没有正确识别到Users表重写后的主键列(user_id),导致生成的外键约束无法匹配users表的唯一约束。

修复步骤

  1. 明确指定外键关联的主键列
    修改RefreshTokens表中userId的定义,直接指定关联Users表的主键列Users.id:
object RefreshTokens: IdTable<UUID>() {
    override val id = uuid("refresh_token_id").entityId()
    // 明确指定关联Users表的主键列
    val userId = reference("user_id", Users.id).uniqueIndex()
    val token = varchar("token", 255)
    val expiresAt = datetime("expires_at")
}
  1. 一次性创建所有关联表
    分步创建表可能导致元数据同步问题,将创建表的代码改为一次性创建两张表:
transaction {
    SchemaUtils.create(Users, RefreshTokens)
}

额外验证

可以手动查看PostgreSQL数据库中的users表,确认user_id列已正确添加PRIMARY KEY约束。如果约束未生成,建议升级到Exposed的最新稳定版本,避免版本兼容问题。


内容的提问来源于stack exchange,提问作者Moe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:53:08