Change theme
Help
Press space for more information.
Show links for this issue (Shortcut: i, l)
Copy issue ID
Previous Issue (Shortcut: k)
Next Issue (Shortcut: j)
Sign in to use full features.
Vote: I am impacted
Notification menu
Refresh (Shortcut: Shift+r)
Go home (Shortcut: u)
Pending code changes (auto-populated)
View issue level access limits(Press Alt + Right arrow for more information)
Unintended behavior
View staffing
Description
Version used: 1.0.3
Devices/Android versions reproduced on: Emulator and Pixel XL
When I try to go from version 3 to 2 I get the following exception:
01-18 09:33:21.376 8183-8248/
Process:
java.lang.IllegalStateException: A migration from 3 to 2 is necessary. Please provide a Migration in the builder or call fallbackToDestructiveMigration in the builder in which case Room will re-create all of the tables.
at android.arch.persistence.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:82)
at android.arch.persistence.room.RoomOpenHelper.onDowngrade(RoomOpenHelper.java:94)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onDowngrade(FrameworkSQLiteOpenHelper.java:128)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:297)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:93)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:193)
Here is my database creation code:
fun createDatabase(application: Application): UserDatabase {
return Room.databaseBuilder(application, UserDatabase::class.java, getDatabaseName(userManager.userId))
.addMigrations(AddStep1_2, DropStep2_1, AddDatum2_3, DropDatum3_2)
.addCallback(UserDatabase.Callback)
.build()
}
Here is my version 2 database class:
@Database(version = 2, entities = [
/* 1 */ Tag::class, Impression::class, Goal::class,
/* 2 */ GoalQuestion::class, Question::class, Step::class, StepCompletion::class//,
/* 3 */ //Datum::class
])
@TypeConverters(ConvertDateTime::class, ConvertStepFrequency::class, ConvertTagId::class, ConvertUUID::class)
abstract class UserDatabase : RoomDatabase() {
...
}
Here are my migrations:
object AddStep1_2 : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
...
}
}
object DropStep2_1 : Migration(2, 1) {
override fun migrate(db: SupportSQLiteDatabase) {
...
}
}
object AddDatum2_3 : Migration(2, 3) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("CREATE TABLE IF NOT EXISTS `Datum` (`key` TEXT NOT NULL PRIMARY KEY, `value` TEXT)")
}
}
object DropDatum3_2 : Migration(3, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS `Datum`")
}
}
-------
Looking at the RoomDatabase source code, lines 536-544, the 'if' conditions are the source of the problem, which will only find forward migrations, even though you have an 'upgrade' variable just above which is false for reverse migrations:
for (int i = firstIndex; i != lastIndex; i += searchDirection) {
int targetVersion = targetNodes.keyAt(i);
if (targetVersion <= end && targetVersion > start) {
result.add(targetNodes.valueAt(i));
start = targetVersion;
found = true;
break;
}
}