更新行时出现“FOREIGN KEY 约束失败”

问题描述 投票:0回答:1

我的 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()
调用上。

android kotlin sqlite android-room
1个回答
0
投票

我建议不要使用

@Update
便捷方法,因为这会更改所有非主键值(user_id 和 active)。

建议使用:-

@Query("UPDATE entry SET action = 1 WHERE id=:id")
suspend fun setActive(id: Long)

这将永远不会尝试更改

user_id
值,并且也不受多个 (2) 暂停函数的影响。

© www.soinside.com 2019 - 2024. All rights reserved.