添加新属性后更新Room数据库版本,使用Migrations仍崩溃求助
Room数据库迁移崩溃问题修复
核心问题分析
- 数据库版本号未同步更新:你的
@Database注解中version仍为1,但迁移是从版本1到2,Room会检测到版本不匹配导致崩溃。 - 迁移逻辑未包含新增字段:你编写的迁移代码创建的临时表结构和旧表完全一致,没有加入你新增的字段,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
相关产品推荐
相关产品推荐

