When upgrading your Android application you often need to change its data model. When the model is stored in SQLite database, then its schema must be updated as well.
However, in a real application, migration is essential as we would want to retain the user existing data even when they upgrade the App.

The Room persistence library allows you to write Migration classes to preserve user data in this manner. Each Migration class specifies a startVersion and endVersion. At runtime, Room runs each Migration class’s migrate() method, using the correct order to migrate the database to a later version.

A migration can handle more than 1 version e.g. if you have a faster path to choose when going version 3 to 5 without going to version 4. If Room opens a database at version 3 and latest version is >= 5, Room will use the migration object that can migrate from 3 to 5 instead of 3 to 4 and 4 to 5.

If there are not enough migrations provided to move from the current version to the latest version, Room will clear the database and recreate so even if you have no changes between 2 versions, you should still provide a Migration object to the builder.

Create New Entity Or Add New Columns 


The following code snippet shows how to define an entity:

@Entity(tableName = "book")
public class Book {
    @PrimaryKey(autoGenerate = true)
    public int id;
    public String name;
    @ColumnInfo(name = "pub_year")
    @Nullable
    public int pubYear;
}
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("CREATE TABLE book (id INTEGER primary key autoincrement NOT NULL,  "
                    + "name TEXT)");
        }
};
//Add column
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
   @Override
   public void migrate(SupportSQLiteDatabase database) {
          database.execSQL("ALTER TABLE book "
                + " ADD COLUMN pub_year INTEGER default 0 NOT NULL");
        }
    };
Room.databaseBuilder(MainActivity.this, AppDatabase.class, AppDatabase.DATABASE_NAME)
                    .addMigrations(MIGRATION_1_2,MIGRATION_2_3).build();

migrate() method is already called inside a transaction and that transaction might actually be a composite transaction of all necessary Migrations.

After the migration process finishes, Room validates the schema to ensure that the migration occurred correctly. If Room finds a problem, it throws an exception that contains the mismatched information.

Related Post

Room Persistence Library How to use DateTime datatype in SQLite Using Room Room: Database Relationships