房间数据库迁移fallbackToDestructiveMigration()不起作用

use*_*612 5 android database-migration kotlin android-room

我正在使用 Room,并在资产文件夹中预填充数据库。对于应用程序更新,我想通过添加新列并用新数据预填充此列来更改此数据库。

数据库从版本 1 自动迁移到版本 2(添加了一个表)。从版本 2 到版本 3,我现在想通过在资产文件夹中提供不同的“database.db”文件并允许破坏性迁移来应用上述更改。

@Database(entities = [Object1::class, Object2::class], version = 3, autoMigrations = [
    AutoMigration (from = 1, to = 2)], exportSchema = true)
abstract class AppDatabase : RoomDatabase() {

    abstract fun dao(): Dao

    companion object {

        private const val DB_NAME = "database.db"

        @Volatile
        private var instance: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(
                context,
                AppDatabase::class.java, "AppDB.db")
                .fallbackToDestructiveMigration()
                .createFromAsset(DB_NAME)
                .build()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我仍然遇到以下异常:

   java.lang.IllegalStateException: A migration from 1 to 3 was required but not found. Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...) or allow for destructive migrations via one of the RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
Run Code Online (Sandbox Code Playgroud)

我不确定为什么还会发生这种情况。我认为它要么提供迁移脚本,要么允许破坏性迁移,从而使迁移有效。

添加评论:-

我尝试过实施迁移,但再次发生与上面相同的异常。当我尝试使用 versionCode 1 重新开始时,我收到“java.lang.IllegalStateException:Room 无法验证数据完整性。看起来您已更改架构但忘记更新版本号。您可以通过增加版本来简单地解决此问题数字。” 我还更改了数据库名称并在清单中添加了 android:allowBackup="false" 。

有任何想法吗?

use*_*612 0

我终于弄清楚问题是什么,它与版本控制或与房间或资产数据库文件相关的任何其他内容无关。

这是依赖注入。

我在 DatabaseModule 类中向 Dagger 提供了数据库,如下所示:

private const val DB_NAME = "database.db"

@InstallIn(SingletonComponent::class)
@Module
class DatabaseModule {

@Provides
fun provideDao(appDatabase: AppDatabase): Dao {
    return appDatabase.dao()
}

@Provides
@Singleton
fun provideAppDatabase(@ApplicationContext appContext: Context): AppDatabase {
    return Room.databaseBuilder(
        appContext,
        AppDatabase::class.java, "AppDB.db")
        .createFromAsset(DB_NAME)
        .build()
}
Run Code Online (Sandbox Code Playgroud)

}

它缺少fallBackToDestructiveMigration() 调用,因此这弄乱了RoomOpenHelper.java 中Room 的内部onUpgrade 调用。

为了解决这个问题,我在 AppDatabase 中进行了 public 调用,并使用它向 DatabaseModule 类中的 Dagger 提供数据库。