I am using Room with a prepopulated database in the assets folder. For an app update, I would like to alter this database by adding a new column and prepopulating this column with new data.
The database was auto-migrated from version 1 to 2 (a table was added). From version 2 to 3, I would now like to apply abovementioned changes by providing a different 'database.db' file in the assets folder and allowing for destructive migration.
@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()
}
}
}
The problem is that I still get the following exception:
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.
I am unsure why this would still happen. I thought it was either providing a migration script or allowing for destructive migration that makes the migration work.
Added Comment:-
I have tried an implemented migration, but the same exception as above happened again. When I try starting over with versionCode 1, I am getting "java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number." I have also changed the database name and added android:allowBackup="false" in the manifest.
Any ideas?
I finally figured out what the problem was, it had nothing to do with the versioning or anything else related to room or the asset db file.
It was dependency injection.
I provided my database to Dagger in a DatabaseModule class as follows:
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()
}
}
It was missing the fallBackToDestructiveMigration() call, so this messed up Room's internal onUpgrade call in RoomOpenHelper.java.
To fix it, I made my buildDatabase call in AppDatabase public and used it to provide the database to Dagger in the DatabaseModule class.