Android Room外键约束失败(787):如何实现文件夹系统?
解决Room数据库删除Folder时的外键约束失败问题
看起来你遇到的是典型的外键关联引用未清理导致的约束错误——当你删除Folder表的记录时,WebSitesWithFolders关联表中还存在引用该folder_id的条目,而Room默认的外键行为是RESTRICT(禁止删除有子记录引用的父条目),所以抛出了代码787的错误。下面是具体的解决方案:
核心思路:设置外键级联删除
要让Room在删除Folder时自动清理关联表中的对应记录,你需要在WebSitesWithFolders实体的外键定义中添加onDelete = ForeignKey.CASCADE规则。
步骤1:修正关联表的外键配置
首先检查你的WebSitesWithFolders实体,确保它的外键定义包含级联删除逻辑:
@Entity( tableName = "WebSitesWithFolders", primaryKeys = ["webSites_id", "folders_id"], foreignKeys = [ // 网站与关联表的外键(可选添加级联,根据你的业务需求) ForeignKey( entity = WebSites::class, parentColumns = ["id"], // 对应WebSites的主键字段 childColumns = ["webSites_id"], onDelete = ForeignKey.CASCADE ), // 关键:文件夹与关联表的外键,添加级联删除 ForeignKey( entity = Folders::class, parentColumns = ["id"], // 对应Folders的主键字段 childColumns = ["folders_id"], onDelete = ForeignKey.CASCADE // 删除文件夹时,自动删除关联表中相关记录 ) ] ) data class WebSitesWithFolders( val webSites_id: Long, val folders_id: Long )
步骤2:更新数据库版本
修改外键定义属于数据库 schema 变更,你需要更新Room数据库的版本号:
@Database( entities = [WebSites::class, Folders::class, WebSitesWithFolders::class], version = 2, // 版本号比之前的数值+1 exportSchema = true ) abstract class AppDatabase : RoomDatabase() { // 声明你的DAO接口 abstract fun webSiteDao(): WebSiteDao abstract fun folderDao(): FolderDao abstract fun webSitesWithFoldersDao(): WebSitesWithFoldersDao }
如果是开发阶段不想写迁移代码,可以临时启用破坏性迁移(会清空数据库数据,上线前记得去掉):
Room.databaseBuilder(context, AppDatabase::class.java, "your_db_name") .fallbackToDestructiveMigration() .build()
备选方案:手动事务删除(不推荐)
如果你暂时不想修改外键配置,也可以通过DAO的事务先删除关联表记录,再删除文件夹:
@Dao interface FolderDao { @Transaction suspend fun deleteFolderAndAssociations(folderId: Long) { // 第一步:删除关联表中该文件夹的所有关联记录 deleteWebSitesWithFoldersByFolderId(folderId) // 第二步:删除文件夹本身 deleteFolderById(folderId) } @Query("DELETE FROM WebSitesWithFolders WHERE folders_id = :folderId") suspend fun deleteWebSitesWithFoldersByFolderId(folderId: Long) @Query("DELETE FROM Folders WHERE id = :folderId") suspend fun deleteFolderById(folderId: Long) }
验证效果
完成上述配置后,当你调用Folder的删除方法时,Room会自动清理WebSitesWithFolders中对应的关联记录,不会再触发外键约束失败的错误。
内容的提问来源于stack exchange,提问作者Сергей
相关产品推荐
相关产品推荐

