使用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表的唯一约束。
修复步骤
- 明确指定外键关联的主键列
修改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") }
- 一次性创建所有关联表
分步创建表可能导致元数据同步问题,将创建表的代码改为一次性创建两张表:
transaction { SchemaUtils.create(Users, RefreshTokens) }
额外验证
可以手动查看PostgreSQL数据库中的users表,确认user_id列已正确添加PRIMARY KEY约束。如果约束未生成,建议升级到Exposed的最新稳定版本,避免版本兼容问题。
内容的提问来源于stack exchange,提问作者Moe
相关产品推荐
相关产品推荐

