Today, most of the apps are supporting offline first functionality and everyone is using Room for that.
To maintain that we also need to manage versions of our an existing database, and here comes the concept of Migrations in the scenario.
Whenever we deploy an update of our app, along with updating the database version, we should also implement database migrations as well otherwise this might lead to crashes in production (this is from experience 😅).
There are two types of Migrations supported by Room
- Automated
- Manual
Automated Migrations
Note: It is supported in room version 2.4.0-alpha01 and higher. If you are using lower version, then you need to go for Manual Migrations
Note: Automated migrations rely on the generated database schema for both the old and the new versions of the database. If
exportSchema
is set tofalse
, or if you have not yet compiled the database with the new version number, then automated migrations fail.
To declare an automated migration between two versions, you need to add auto migration like below:
If you get the error like “Schema required for migration are not found at path:…”, then in the build.gradle file for your app module, add the following. This will write out the schema to a schema sub folder of your project folder.
If Room is unable to generate a migration due to ambiguous schema changes, it will throw a compile time error and ask for a AutoMigrationSpec. This will occur if a migration involves deleting or renaming of a table or column.
You can add a AutoMigrationSpec as follows:
Now, let’s look at another type of migrations
Manual Migrations
If your migration includes complex schema changes like creating a new table or adding a new column in a table, you must implement manual migration using Migration class as follows:
Each Migration class defines a path between start version and end version by overriding the migrate() method. And you need to add your migrations to database builder using addMigrations() method.
If Room cannot find a migration to upgrade an existing database on a device, an IllegalStateException can occur. Only if it is okay to loose existing data when a migration is not provided, you can call fallbackToDestructiveMigration() method with database builder.
Now we know about migrations, we can update our database in production safely without loosing existing data (and without crashes hopefully 😜).
That’s it for now. To stay tuned for my further articles follow me and let’s connect on LinkedIn here