You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Room 查询新建workout时getWorkoutSteps未返回对应steps数据

问题原因与解决方案

根据你的描述,该问题通常由以下几种常见的Room操作疏漏导致,可逐一排查修复:

  • 返回值类型不匹配

检查你的stepDao.getWorkoutSteps方法定义:
如果该方法返回值是Flow<List<Step>>/LiveData<List<Step>>这类可观察类型,直接赋值给普通列表变量只会拿到可观察对象本身,而非实际查询结果。你硬编码id能返回数据,大概率是测试时对可观察对象做了订阅取值。
修正方案:将查询方法改为直接返回列表的挂起函数:

@Query("SELECT * FROM step WHERE workoutId = :workoutId")
suspend fun getWorkoutSteps(workoutId: Long): List<Step>
  • 事务未统一导致的读写不一致

你当前插入Workout、插入Step、查询Step是三个独立的数据库操作,未包裹在同一事务中,可能出现插入操作还未完成持久化就触发查询的情况。
修正方案:将新建场景的所有数据库操作包裹在同一事务内:

viewModelScope.launch {
    workout?.let { workout ->
        steps = stepDao.getWorkoutSteps(workout.workoutId)
        Log.e(tag, "steps old : ${workout.workoutId}")
    } ?: run {
        // db为你的RoomDatabase实例
        db.withTransaction {
            newWorkoutAndStepsId = workoutDao.insert(Workout(""))
            Log.e(tag, "steps new : $newWorkoutAndStepsId")

            val step1id = stepDao.insert(Step("Warm Up Jumping Jacks", 1, false, "minute", newWorkoutAndStepsId))
            Log.e(tag, "steps new : new step id $step1id")
            stepDao.insert(Step("Rest", 15, true, "second", newWorkoutAndStepsId))

            steps = stepDao.getWorkoutSteps(newWorkoutAndStepsId)
        }
    }
}
  • 类型转换溢出

Room的insert方法默认返回Long类型的行id,你直接调用toInt()如果生成的id超过Int的最大值会出现溢出,导致查询时传入的id和实际存储的workout id不一致。
修正方案:将Workout的主键、Step中关联的workoutId字段统一改为Long类型,去掉不必要的toInt()转换。

  • 实体字段与查询条件不匹配

检查Step实体类的字段定义,确认关联Workout的外键字段名、类型与查询语句中的条件完全一致,例如查询语句中用的是workoutId = :id,则Step类中对应的字段必须命名为workoutId,且类型和Workout主键类型一致。

内容的提问来源于stack exchange,提问作者salah1337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:09:04