我的 Room 数据库中有两个实体:
@Entity(
tableName = "user",
primaryKeys = ["id"],
)
data class User(
@ColumnInfo(name = "id")
val userId: Long,
// Other columns here
)
@Entity(
tableName = "entry",
primaryKeys = ["id"],
foreignKeys = [
ForeignKey(
entity = User::class,
parentColumns = ["id"],
childColumns = ["user_id"],
onDelete = ForeignKey.CASCADE,
),
],
)
data class Entry(
@ColumnInfo(name = "id")
val id: Long,
@ColumnInfo(name = "user_id")
val userId: Long,
@ColumnInfo(name = "active")
val active: Boolean,
)
我也有 DAO 来操作这些。相关的 DAO 方法是更新条目的“活动”列的方法:
@Query("SELECT * FROM entry WHERE id = :id")
suspend fun getEntry(id: Long): Entry?
@Update
suspend fun updateEntry(entry: Entry)
然后,我有这个代码可以更新活动状态:
suspend fun setActive(entryId: Long) {
val entry = dao.getEntry(entryId)
entry?.let {
dao.updateEntry(entry.copy(active = true))
}
}
但是,在某些用户的生产中,调用
setActive()
函数会抛出 SQLiteConstraintException: error code 19: FOREIGN KEY constraint failed
。可能是什么原因造成的?据我所知,如果删除用户, onDelete = CASCADE 应该删除条目。我的日志似乎没有表明抛出是否发生在 getEntry()
调用或 updateEntry()
调用上。
我建议不要使用
@Update
便捷方法,因为这会更改所有非主键值(user_id 和 active)。
建议使用:-
@Query("UPDATE entry SET action = 1 WHERE id=:id")
suspend fun setActive(id: Long)
这将永远不会尝试更改
user_id
值,并且也不受多个 (2) 暂停函数的影响。