【问题标题】:FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY) when add data to table room将数据添加到表室时,FOREIGN KEY 约束失败(代码 787 SQLITE_CONSTRAINT_FOREIGNKEY)
【发布时间】:2021-11-18 09:57:51
【问题描述】:

当我尝试添加时,我必须表 CheckListModel 和 CheckListPoints,这是一对多的关系 DB CheckListModel 中的数据正确添加,但是当代码开始添加 CheckListPoints 时出现此错误。我不知道为什么会这样

这是我的数据库

@Database(entities = [CheckListModel::class,CheckListPoints::class],version = 4,exportSchema = false)
abstract class CheckListDB : RoomDatabase() {

    abstract fun checkListDBDao():CheckListModelDBDao

    companion object {

        @Volatile
        private var instance: CheckListDB? = null

        fun getInstance(context: Context):CheckListDB{
            return instance ?: synchronized(this){
                instance?: buildDatabase(context).also { instance = it }
            }
        }
        private fun buildDatabase(context: Context): CheckListDB{
            return Room.databaseBuilder(context,CheckListDB::class.java,"check_list_model").fallbackToDestructiveMigration().build()
        }
    }
}

实体

@Entity(
    tableName = "check_list_point",
    foreignKeys = [
        ForeignKey(entity = CheckListModel::class, parentColumns = ["checkListModelID"],childColumns = ["checkListColumnID"],onDelete = ForeignKey.CASCADE)
    ],
    indices = [Index("checkListColumnID")]
)
data class CheckListPoints(
    @ColumnInfo(name = "correctly")
    var correctly: Boolean,
    @ColumnInfo(name = "requirement")
    var requirement: String,
    @ColumnInfo(name = "passed")
    var passed: Boolean,
    @ColumnInfo(name="checkListColumnID")
    val checkListColumnID: Long,
    @PrimaryKey(autoGenerate = true)
    val checkListPointsModelID: Long = 0L
): Serializable

@Entity(tableName = "check_list_model")
data class CheckListModel (
    @ColumnInfo(name = "check_list_name")
    val checkListName: String,
    @ColumnInfo(name = "check_list_count")
    val checkListCount: Int,
    @ColumnInfo(name = "check_list_result")
    val checkListResult: Int,
    @ColumnInfo(name = "description")
    val description: String,
    @PrimaryKey(autoGenerate = true)
    val checkListModelID: Long = 0L
        ) : Serializable

关系

data class CheckListWithCheckListModel(
    @Embedded val CheckList: CheckListModel,
    @Relation(
        parentColumn = "checkListModelID",
        entityColumn = "checkListColumnID"
    )
    val checkListPoints: List<CheckListPoints>
)

这是道

@Dao
interface CheckListModelDBDao {

    @Insert
    fun insertCheckList(data:CheckListModel)

    @Insert
    fun insertCheckListPoint(vararg data:CheckListPoints)

    @Delete
    fun deleteCheckList(checkList: CheckListModel)

    @Transaction
    @Query("SELECT * FROM check_list_model " )
    fun getEverything(): Flow<List<CheckListWithCheckListModel>>
}

这就是我添加的方式

    private var doorCheckListModel = CheckListModel("Дверь",0,0,"4321")
    private val doorCheckListPoint1 = CheckListPoints(false,"1",false,doorCheckListModel.checkListModelID)
    private val doorCheckListPoint2 = CheckListPoints(false,"2",false,doorCheckListModel.checkListModelID)
    private var doorListOfCheckListPoints = listOf<CheckListPoints>(doorCheckListPoint1,doorCheckListPoint2)

    private var windowCheckListModel = CheckListModel("Окно",0,0,"4321")
    private var windowCheckListPoint1 = CheckListPoints(false,"1",false,windowCheckListModel.checkListModelID)
    private var windowCheckListPoint2 = CheckListPoints(false,"1",false,windowCheckListModel.checkListModelID)
    private var windowListOfCheckListPoints = listOf<CheckListPoints>(windowCheckListPoint1,windowCheckListPoint2)

    var checkLists = MutableLiveData<List<CheckListModel>>().apply {
        value = listOf(doorCheckListModel,windowCheckListModel)
    }

    fun addCheckList(name: String){
        viewModelScope.launch(Dispatchers.IO) {
            when (name) {
                "Дверь" -> insert(doorCheckListModel,doorListOfCheckListPoints)
                "Окно" -> insert(windowCheckListModel,windowListOfCheckListPoints)
            }
        }
    }

    private suspend fun insert(checkList: CheckListModel, checkListPoints: List<CheckListPoints>){
        database.insertCheckList(checkList)
        for(checkListPoint in checkListPoints){
            database.insertCheckListPoint(checkListPoint)
        }
    }
}

我还在片段中显示来自 CheckListModel 的数据。 CheckListModel 正确添加到 DB 并正确显示,但 CheckListPoints 没有

【问题讨论】:

  • 在这里分享 logcat 错误...

标签: kotlin android-room


【解决方案1】:

当您创建doorCheckListModel 时,其checkListModelID 最初为0。您将此0 用作doorCheckListPoint1 中的checkListColumnID。所以当你保存CheckListModel时,Room会自动生成主键并保存在表中。 CheckListPoints 表中的主键也是如此。但是CheckListPoints表中保存的条目在checkListColumnID列中仍然有0。

这就是外键约束失败的原因。没有以 0 作为主键的 CheckListModel。要解决此问题,您必须先设置 checkListColumnID 的值,然后再将 CheckListPoints 条目保存到表中。

如果您通过 Room documentation,@Insert 注释函数可以选择返回插入项目的 rowId。对于整数主键,rowId 与主键相同。

试试这个代码:

// Return the primary key here
@Insert
fun insertCheckList(data:CheckListModel): Long
private suspend fun insert(checkList: CheckListModel, checkListPoints: List<CheckListPoints>){
    val id = database.insertCheckList(checkList)
    for(checkListPoint in checkListPoints){
        database.insertCheckListPoint(checkListPoint.copy(checkListColumnID = id))
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多