The Pain of Manual Migrations
Before Room 2.4.0, every time you added a column or changed a table structure, you had to write manual Migration objects. This involved writing error-prone SQL strings and incrementing version numbers by hand. If you missed a single comma, your app would crash on launch for existing users. Room's Auto-Migration feature changes that by automating the diffing process between your old and new database schemas.
Setting the Foundation
To use auto-migrations, you must first ensure your database exports its schema. Room needs these generated JSON files to understand what the database looked like in previous versions. Update your build.gradle file to specify the schema location:
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
}
In your @Database class, set exportSchema = true. This tells Room to save the schema definition into your project folder every time you compile.
Implementing a Basic Auto-Migration
If you are simply adding a new table or a nullable column, Room can handle the transition without any extra logic. You only need to increment the version and add the autoMigrations parameter to the annotation.
@Database(
version = 2,
entities = [User::class, Product::class],
autoMigrations = [
AutoMigration(from = 1, to = 2)
],
exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
// ...
}
Handling Complex Changes
Room is smart, but it isn't a mind reader. If you rename a column or delete a table, Room doesn't know if you intended to move data or start fresh. In these cases, you must provide an AutoMigrationSpec. For example, if you rename a column in the User table from fullName to userName, you would do the following:
@RenameColumn(tableName = "User", fromColumnName = "fullName", toColumnName = "userName")
class MyAutoMigration : AutoMigrationSpec
// Then reference it in your Database annotation:
@Database(
version = 3,
entities = [User::class],
autoMigrations = [
AutoMigration(from = 2, to = 3, spec = MyAutoMigration::class)
],
exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
// ...
}
Why This Matters
Auto-migrations significantly reduce the surface area for bugs. Because Room generates the migration code during compilation, it validates your schema against the entities automatically. If you make a mistake, you get a compile-time error rather than a runtime crash. For production apps, this means smoother updates and fewer frustrated users. While complex data transformations still require manual migration scripts, auto-migrations handle 90% of daily development tasks with ease.







