Я пишу тест, следуя этим инструкциям. В моем тестовом классе есть это правило:
@Rule
public MigrationTestHelper testHelper = new MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
AppDatabase.class.getCanonicalName(),
new FrameworkSQLiteOpenHelperFactory()
);
и мой тест выглядит следующим образом:
@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.MIGRATIONat 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)
10);
...
}
Но это терпит неудачу в последней строке (предыдущие утверждения прошли хорошо), говоря следующее:
java.lang.IllegalStateException: Комната не может проверить целостность данных. Похоже, вы изменили схему, но забыли обновить номер версии. Вы можете просто исправить это, увеличив номер версии.
Что неправильно. Я проследил, что происходит:
- создать базу данных с идентификационным хэшем версии 9
- вставить данные
- проверить данные
- call
runMigrationsAndValidate
, which:- opens the database
- проверяет хэш идентификации на версию 10 и терпит неудачу
При проверке хэша идентификации он делает:
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.");
}
}
Таким образом, загруженный identityHash
- это тот, который загружен из БД версии 9; а mIdentityHash
загружается непосредственно runMigrationsAndValidate
с использованием параметра версии, равного 10.
Так что конечно не получается.
Мне интересно, почему он проверяет хэши идентификаторов ДО выполнения миграции.
Вот миграция, даже если я думаю, что она здесь не актуальна:
public static final Migration MIGRATIONat 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)
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();
}
};
Я сделал что-то не так?
PS: вот полная трассировка стека, если это интересно:
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)
Я использую (versions.arch
равно 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}"