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

添加新属性后更新Room数据库版本,使用Migrations仍崩溃求助

Room数据库迁移崩溃问题修复

核心问题分析

  1. 数据库版本号未同步更新:你的@Database注解中version仍为1,但迁移是从版本1到2,Room会检测到版本不匹配导致崩溃。
  2. 迁移逻辑未包含新增字段:你编写的迁移代码创建的临时表结构和旧表完全一致,没有加入你新增的字段,Room初始化时会发现实体类与实际表结构不符,触发崩溃。

修复步骤

1. 更新数据库版本号

修改@Database注解中的版本号为2:

@Database(entities = [Reminder::class], version = 2)
abstract class ReminderDatabase : RoomDatabase() {
    // 其余代码保持不变
}

2. 修正迁移逻辑,加入新增字段

假设你新增的字段为newVal TEXT(请根据实体类中实际的字段名、类型调整),修改迁移代码:

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        // 创建包含新增字段的临时表
        database.execSQL(
            "CREATE TABLE Reminder_2 (" +
                    "id INTEGER NOT NULL, " +
                    "title TEXT, " +
                    "note TEXT, " +
                    "date TEXT, " +
                    "newVal TEXT, " + // 新增字段,与实体类定义一致
                    "PRIMARY KEY(id))"
        )

        // 迁移旧数据,为新增字段设置默认值(示例为空字符串,按需调整)
        database.execSQL("INSERT INTO Reminder_2 (id, title, note, date, newVal) SELECT id, title, note, date, '' FROM Reminder")

        // 替换旧表
        database.execSQL("DROP TABLE Reminder")
        database.execSQL("ALTER TABLE Reminder_2 RENAME TO Reminder")
    }
}

3. 校验实体类与迁移字段一致性

确保Reminder实体类中的新增字段与迁移SQL中的字段名、数据类型完全匹配,例如:

@Entity(tableName = "Reminder")
data class Reminder(
    @PrimaryKey val id: Int,
    val title: String?,
    val note: String?,
    val date: String?,
    val newVal: String? // 需与迁移代码中的字段定义一致
)

注意事项

  • 如果新增字段为非空类型,需在SQL中指定默认值(如newVal TEXT NOT NULL DEFAULT 'default_value'),并在插入语句中对应设置默认值。
  • 测试前建议备份用户数据,避免迁移过程中数据丢失。

内容的提问来源于stack exchange,提问作者Yahya Melih Koşar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:04:59