Android Room插入无外键表触发FOREIGN KEY约束异常
问题分析与解决方案
出现FOREIGN KEY constraint failed (code 787)的核心原因是Tag类缺少@Entity注解,同时数据库实体配置存在矛盾:
Tag类被加入到RoomDB的entities列表中,且StationTagMap的外键直接依赖Tag实体,但Tag本身没有标记@Entity注解,导致Room无法正确创建tags表,数据库外键约束逻辑因此失效,进而在插入Station时触发异常(虽然插入操作本身不涉及StationTagMap,但数据库初始化时的外键约束校验会被触发)。
另外,还有两处需要修正的细节:
1. 为Tag类添加@Entity注解
修改Tag.kt,给Tag数据类加上@Entity注解并指定表名:
@Entity(tableName = Tag.TABLE_NAME) data class Tag( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "rowid") var rowid: Long, @ColumnInfo(name = "tagName") var tagName: String?, ) { companion object { const val TABLE_NAME = "tags" } }
2. 修正StationWithTags的@Relation配置
当前@Relation中的entityColumn和parentColumn配置冗余且易混淆,使用Junction时,只需指定关联表的映射列即可,父实体和子实体的主键会自动匹配。修正后的代码:
data class StationWithTags( @Embedded var station: Station, @Relation( entity = Tag::class, associateBy = Junction( value = StationTagMap::class, parentColumn = "stationIdMap", entityColumn = "tagIdMap" ) ) var tags: List<Tag>, ) { companion object { const val TABLE_NAME = "stations_t" } }
3. 重置数据库(测试阶段)
由于之前的数据库可能存在结构异常,测试时需要:
- 卸载当前应用,清除旧的数据库文件
- 或者修改RoomDB的版本号(比如从1改为2),让Room自动重建数据库
验证插入操作
完成上述修改后,重新运行代码,插入Station的操作即可正常执行,不会再触发外键约束异常。
内容的提问来源于stack exchange,提问作者user2516873
相关产品推荐
相关产品推荐

