Room数据库更新日志正常但值未保存,RecyclerView拖拽排序位置不生效
RecyclerView拖拽重排后Room位置更新不生效解决方案
核心问题排查
- 你手动添加的
Timber.i日志仅代表代码执行到了setCpPosition方法,完全不能证明Room实际执行了对应的UPDATE SQL语句,这是你首先要纠正的认知误区。 - 核心错误:DAO中的
setCpPosition方法缺少suspend修饰,你在带@Transaction注解的挂起方法swapCpPosition中调用普通同步DAO方法,Room不会将该操作纳入当前事务执行,SQL语句最终没有提交到数据库。
修复步骤
- 修改DAO层
setCpPosition方法,添加suspend修饰,可同时返回Int类型验证更新影响的行数:
@Query("update cp_view_group set position =:pos where cp_id=:cpID") suspend fun setCpPosition(pos: Int, cpID: Long): Int
- 调整
swapCpPosition方法,可添加日志确认更新生效情况:
@Transaction suspend fun swapCpPosition(fromID: Long, fromPos: Int, toID: Long, toPos: Int) { val updateFromRows = setCpPosition((toPos+1), fromID) val updateToRows = setCpPosition((fromPos+1), toID) Timber.i("更新行数:fromId影响$updateFromRows 行,toId影响$updateToRows 行") }
- 若打印的影响行数为0,进一步校验以下配置:
- 表名
cp_view_group是否和实体类@Entity注解中定义的表名完全一致 - 列名
position、cp_id是否和实体类字段的@ColumnInfo注解定义的列名完全匹配 - 传入的
cpID值是否真实存在于cp_view_group表中
- 表名
可选验证方案
开启Room原生SQL执行日志,确认SQL实际执行情况:
构建Database实例时添加日志配置,或执行adb命令adb shell setprop log.tag.RoomSQLiteQuery VERBOSE,过滤RoomSQLiteQuery标签即可看到Room实际执行的SQL语句、参数和执行结果。
内容的提问来源于stack exchange,提问作者Pemba Tamang
相关产品推荐
相关产品推荐

