Room插入Book时报SQLite外键约束失败(787错误)求助
Room插入Book实体触发SQLite外键约束错误排查
问题场景
尝试向Room数据库插入Book实体时触发如下错误:
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY[787]) at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:1127) at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
对应的Book实体代码:
@Entity( tableName = "books", foreignKeys = [ForeignKey( entity = Account::class, parentColumns = arrayOf("user_id"), childColumns = arrayOf("book_id"), onDelete = ForeignKey.CASCADE )] ) data class Book( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "book_id") val book_id: Long = 0, @ColumnInfo(index = true) val user_id: Long = 0, val title: String = "", val note: String = "" )
实体与Account为1:1关联。
错误原因
外键关联的列配置完全颠倒:
parentColumns指定的是Account表的user_id,但childColumns错误指向了Book自身的主键book_id,这导致Room要求Book的book_id必须匹配Account中已存在的user_id,完全不符合1:1关联的逻辑。- 正确的关联逻辑应该是Book通过
user_id字段关联到Account的user_id。
修复方案
修改外键的childColumns为user_id,同时确保Account表的user_id是主键或唯一键(这是外键关联的必要前提):
@Entity( tableName = "books", foreignKeys = [ForeignKey( entity = Account::class, parentColumns = arrayOf("user_id"), childColumns = arrayOf("user_id"), // 修正为user_id onDelete = ForeignKey.CASCADE )] ) data class Book( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "book_id") val book_id: Long = 0, @ColumnInfo(index = true) val user_id: Long = 0, val title: String = "", val note: String = "" )
额外注意事项
- 插入顺序必须是先插入Account记录,再插入对应的Book记录,且Book的
user_id必须与已插入的Account的user_id完全匹配。 - 确保Account实体的
user_id字段被标记为@PrimaryKey或@Unique,否则外键约束无法正常生效。
内容的提问来源于stack exchange,提问作者Alix Blaine
相关产品推荐
相关产品推荐

