I am writing a test following these instructions. My test class has this rule:
@Rule
public MigrationTestHelper testHelper = new MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
AppDatabase.class.getCanonicalName(),
new FrameworkSQLiteOpenHelperFactory()
);
and my test is as follows:
@Test
public void testMigration9_10() throws IOException {
// Create the database with version 9
SupportSQLiteDatabase db = testHelper.createDatabase(TEST_DB_NAME, 9);
// Insert before migration
ContentValues values = new ContentValues();
values.put("rowid", 1);
...
db.insert("foo", SQLiteDatabase.CONFLICT_FAIL, values);
// Check inserted data
Cursor c = db.query("SELECT * FROM foo WHERE rowid = " + values.get("rowid"));
Assert.assertTrue(c.moveToFirst());
Assert.assertEquals(c.getString(c.getColumnIndex("rowid")), values.get("rowid"));
// Migrate
db = testHelper.runMigrationsAndValidate(TEST_DB_NAME, 10, true, DatabaseCreator.MIGRATION_9_10);
...
}
But this fails at the last line (the previous assertions went well), saying this:
java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
Which is wrong. I have traced what happens:
- create the database with the version 9 identity hash
- insert data
- check data
- call
runMigrationsAndValidate
, which:- opens the database
- checks the identity hash against version 10, and fails
When checking the identity hash, it does:
private void checkIdentity(SupportSQLiteDatabase db) {
createMasterTableIfNotExists(db);
String identityHash = "";
Cursor cursor = db.query(new SimpleSQLiteQuery(RoomMasterTable.READ_QUERY));
//noinspection TryFinallyCanBeTryWithResources
try {
if (cursor.moveToFirst()) {
identityHash = cursor.getString(0);
}
} finally {
cursor.close();
}
if (!mIdentityHash.equals(identityHash)) {
throw new IllegalStateException("Room cannot verify the data integrity. Looks like"
+ " you've changed schema but forgot to update the version number. You can"
+ " simply fix this by increasing the version number.");
}
}
So the loaded identityHash
is the one loaded from the DB, which is in version 9; and mIdentityHash
is the one loaded directly by runMigrationsAndValidate
using the version parameter, which is 10.
So of course it fails.
I'm wondering why it is checking the identity hashes BEFORE doing the migrations.
Here's the migration, even if I think it's not relevant here:
public static final Migration MIGRATION_9_10 = new Migration(9, 10) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.beginTransaction();
database.execSQL("ALTER TABLE DeclarationEntity ADD latitude REAL NOT NULL DEFAULT 0.0");
database.execSQL("ALTER TABLE DeclarationEntity ADD longitude REAL NOT NULL DEFAULT 0.0");
database.endTransaction();
}
};
Did I do something wrong?
PS: here's the full stack trace in case this is interesting:
at android.arch.persistence.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:119)
at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:100)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:133)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:282)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:175)
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.testing.MigrationTestHelper.openDatabase(MigrationTestHelper.java:203)
at android.arch.persistence.room.testing.MigrationTestHelper.runMigrationsAndValidate(MigrationTestHelper.java:193)
I'm using (versions.arch
being 1.0.0):
implementation "android.arch.persistence.room:runtime:${versions.arch}"
annotationProcessor "android.arch.persistence.room:compiler:${versions.arch}"
androidTestImplementation "android.arch.persistence.room:testing:${versions.arch}"
Aucun commentaire:
Enregistrer un commentaire