Re-phrasing a previous question … The database in...
# room
b
Re-phrasing a previous question … The database in our app is essentially just a temporary cache of server data. As such, it’s perfectly acceptable (and sometimes even desireble) to wipe out all data when we release new versions. So, we’ve never used migrations, and we employ
fallbackToDestructiveMigration()
to facilitate new versions. No problem. In the newest version, we have removed a table/entity. Compounding things, that table/entity had a foreign key. When the new version is installed, Room does NOT remove the old table (I understand why). So, we need to define an AutoMigration and use
@DeleteTable
to remove the old table that is no longer needed. Our new database is version 5 (previous version that had the table was 4). So I’ve defined an Automigration with
(from = 4, to = 5, spec = MyMigrationSpec::class)
. Sure enough if I have the app installed with db version 4 and then install a new build that has db version 5, the migration runs and the table is deleted. But, if I have an older build of the app installed with say db version 2, and then I install a new build with db version 5, the migration does NOT run and the table is NOT deleted. I added an
onPostMigrate
implementation with some debug code to confirm that it doesn’t run. What gives? even though I’m going from 2 -> 5, I thought it would find the version 4 schema, and do a (destructive) migration from 2 -> 4 and then apply the the AutoMigration from 4-> 5 … But that doesn’t seem to be the case. Surely I don’t have to create my own migrations for every possible combination of from/to versions that users could be updating across, right?
Answering my own question here … We can add a callback to the database builder and implement it’s
onDestructiveMigration
method. In there, we can drop the table whose Entity has been removed. I still don’t understand why the automigration we setup doesn’t run, but we no longer need it with this solution. Here’s a full example:
Copy code
Room.databaseBuilder(app, AppDatabase::class.java, "AppDB")
            .fallbackToDestructiveMigration() 
            .addCallback(object: RoomDatabase.Callback() {
                override fun onDestructiveMigration(db: SupportSQLiteDatabase) {
                    super.onDestructiveMigration(db)
                    db.execSQL("DROP TABLE IF EXISTS CrustyOldTable;")
                }
            })
            .build()