Ich erhalte diesen Fehler, wenn ich ein Programm mit Room Database ausführe
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.
Es scheint, dass wir die Datenbankversion aktualisieren müssen, aber von wo aus können wir das in Room tun?
Antworten:
Wenn Sie zum ersten Mal auf diese Nachricht stoßen, arbeiten Sie höchstwahrscheinlich gegen eine unveröffentlichte Version der Datenbank. In diesem Fall sollten Sie die Datenbankversion höchstwahrscheinlich nicht erhöhen . Durch einfaches Löschen der App-Daten haben Sie die Ausnahme bestanden.
Wenn Sie die Datenbank nicht erhöhen (empfohlen):
Sie sollten die App-Daten der Anwendung aus den Android-Einstellungen löschen. Alternativ können Sie möglicherweise die vorherige App-Version deinstallieren und dann die neue Version installieren, um die Ausnahme zu übergeben. Dieser letztere Ansatz funktioniert unter bestimmten Bedingungen nicht (z. B. wenn die Option "Sicherung zulassen" aktiviert ist).
Da das Löschen von Anwendungsdaten immer funktioniert, gehe ich jedes Mal diesen Weg.
Wenn Sie die Datenbankversion erhöhen:
Sie müssen Datenbankmigrationscode schreiben, um Änderungen am Datenbankschema zu berücksichtigen. Sehen Sie hier für Informationen zu Migration.
Alternativ zum Schreiben des Datenbankmigrationscodes können Sie
fallbackToDestructiveMigration
den Room Database Builder aufrufen . Dies ist wahrscheinlich keine gute Idee. Wenn Sie vergessen, diesen Aufruf zu entfernen und dann die Datenbank zu aktualisieren, gehen Daten verloren.// Using this fallback is almost certainly a bad idea Database database = Room.databaseBuilder(context, Database.class, DATABASE_NAME) .fallbackToDestructiveMigration() .build();
Auch hier ist weder ein Inkrementieren der Datenbankversion noch ein Zurückgreifen auf eine destruktive Migration erforderlich, wenn das vorherige Datenbankschema nicht in freier Wildbahn ausgeführt wird .
quelle
1.0.0-rc1
von Room war das einzige, was für mich funktioniert hat, die Datenbankversion zu erhöhen.Standardmäßig haben Android-Manifeste
android:allowBackup="true"
, mit denen Apps ihre SQLite-Datenbank bei Neuinstallation beibehalten können.Angenommen, Sie
DATABASE_VERSION
waren anfangs 3 und dann entscheiden Sie sich, die DB-Version von 3 auf 1 zu reduzieren.@Database(entities = {CallRecording.class}, version = DATABASE_VERSION) public abstract class AppDatabase extends RoomDatabase { public abstract RecordingDAO recordingDAO(); // static final Migration MIGRATION_1_2 = new Migration(1, 2) { // @Override // public void migrate(SupportSQLiteDatabase database) { // // Since we didn't alter the table, there's nothing else to do here. // } // }; }
Sie können es so erreichen
Es ist eine gute Praxis,
DATABASE_VERSION
so konstant wie möglich zu bleiben .quelle
android: allowBackup = "true" in AndroidManifest.xml verhindert, dass die Daten auch nach der Deinstallation der App gelöscht werden.
Fügen Sie dies Ihrem Manifest hinzu:
android:allowBackup="false"
und installieren Sie die App neu.
Hinweis: Stellen Sie sicher, dass Sie es später wieder auf true ändern, wenn Sie automatische Sicherungen wünschen.
Eine andere Lösung:
Überprüfen Sie den identityHash Ihrer alten json-Datei und der neuen json-Datei im Ordner apps \ schema.
Wenn der identityHash unterschiedlich ist, wird dieser Fehler ausgegeben. Finden Sie heraus, was Sie geändert haben, indem Sie beide JSON-Dateien vergleichen, wenn Sie nichts ändern möchten.
Stellen Sie sicher, dass Sie exportSchema = true haben.
@Database(entities = {MyEntity.class, ...}, version = 2, exportSchema = true)
JSON-Schemadatei:
"formatVersion": 1, "database": { "version": 2, "identityHash": "53cc5ef34d2ebd33c8518d79d27ed012", "entities": [ {
Code:
private void checkIdentity(SupportSQLiteDatabase db) { String identityHash = null; if (hasRoomMasterTable(db)) { 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) && !mLegacyHash.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."); } }
quelle
Aniruddh Parihars Antwort gab mir einen Hinweis und es löste sich.
Suchen Sie nach einer Klasse, in der Sie erweitert haben
RoomDatabase
. Dort finden Sie die folgende Version:@Database(entities = {YourEntity.class}, version = 1)
Erhöhen Sie einfach die Version und das Problem ist gelöst.
quelle
Es ist sehr einfach, wie im Protokoll gezeigt
Looks like you've changed schema but forgot to update the Database version number. You can simply fix this by increasing the version number.
Gehen Sie einfach zu Ihrer Datenbankversionsklasse und aktualisieren Sie Ihre DB-Version, indem Sie 1 von der aktuellen erhöhen.
@Database(entities = {YourEntityName.class}, version = 1)
quelle
It seems we need to update database version
. Aber ich kam nicht dahin, wo diese Version erwähnt wurde. Trotzdem danke für diesen Hinweis.1: - Es scheint, dass wir die Datenbankversion aktualisieren müssen (um 1 erhöhen)
2. Deinstallieren Sie die App oder löschen Sie die App-Daten
quelle
Auf Android-Handy:
So löschen Sie App-Daten: Gehen Sie zu Einstellungen -> Apps -> Wählen Sie Ihre App aus -> Speicher -> Daten löschen
Die Deinstallation (und Neuinstallation) funktioniert nicht in jedem Fall. Versuchen Sie also zuerst, Daten zu löschen!
quelle
In meinem Fall
android:allowBackup="false"
ist es das Seltsamste, warum diese Einstellung standardmäßig aktiviert ist, da dies auch zu Albträumen geführt hat.quelle
Um das Problem in Kotlin zu beheben:
Zuerst
@Database(entities = [Contact::class], version = 2)
Zweite
val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE Contact ADD COLUMN seller_id TEXT NOT NULL DEFAULT ''") } }
Dritte
private fun buildDatabase(context: Context) = Room.databaseBuilder( context.applicationContext, EpayDatabase::class.java, "epay" ) .addMigrations(MIGRATION_1_2) .build()
Weitere Informationen finden Sie in der offiziellen Dokumentation
quelle
Dieses Problem tritt hauptsächlich in der Entwicklung auf.
Wenn Sie Ihr Schema ändern, dh Ihre Klasse mit Tabellenentität umbenennen / hinzufügen / ändern, widerspricht die Integrität zwischen dem Beenden von db in Ihrem vorherigen Build einem neuen Build.
Jetzt wird die alte Datenbank nicht mit der neueren in Konflikt geraten.
quelle
android:allowBackup="true"
und benutze es mit BedachtIn meinem Fall hatte ich eine AppDatabase-Klasse.
@Database(entities = {GenreData.class, MoodData.class, SongInfo.class, AlbumsInfo.class, UserFolderListsData.class, UserPlaylistResponse.PlayLists.class, InternetConnectionModel.class}, version = 3, exportSchema = false)
Ich habe diese Versionsnummer aktualisiert und das Problem behoben. Das Problem trat auf, weil ich eine Eigenschaft in der SongInfo-Klasse hinzugefügt und vergessen hatte, die Versionsnummer zu aktualisieren.
Hoffe es hilft jemandem.
quelle
Wenn Sie die Room-Version von der alten Version auf 1.0.0-alpha9 aktualisieren, besuchen Sie bitte den folgenden Artikel. Sehr guter Artikel für die Migration von der alten Version auf die Version 1.0.0-alpha9.
https://medium.com/@manuelvicnt/android-room-upgrading-alpha-versions-needs-a-migration-with-kotlin-or-nonnull-7a2d140f05b9
In Room New Version 1.0.0-alpha9 bietet Room Unterstützung für die NOT NULL-Einschränkung.
Dadurch wird das von Room generierte Schema geändert. Da es das Schema ändert, ändert es auch den identityHash der Datenbank, der von Room verwendet wird, um jede DB-Version eindeutig zu identifizieren. Deshalb brauchen wir eine Migration
quelle
In meinem Fall arbeiten ContentProvider und Raumdatenbank zusammen. Entfernen Sie daher zunächst alle Rückrufe von ContentProvider in der gesamten Anwendung mit der Datenbankklasse, die die SqlLiteOpenHelper-Klasse erweitert
quelle
In meinem Fall habe ich eine Transaktion innerhalb der Migration verwendet und Room konnte den Hash nicht mit einem Migrationshelfer aktualisieren
@get:Rule val migrationTestHelper: MigrationTestHelper = MigrationTestHelper(InstrumentationRegistry.getInstrumentation(), C2GDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory()) /* Testing method throws error*/ db = migrationTestHelper.runMigrationsAndValidate(C2GDatabase.DB_NAME, 3, false, C2GDatabase.Migration_1_2(), C2GDatabase.Migration_2_3()) override fun migrate(database: SupportSQLiteDatabase) { /** Error database.beginTransaction() **/ database.execSQL("PRAGMA foreign_keys=off;") database.execSQL("ALTER TABLE user RENAME TO user_old;") database.execSQL("CREATE TABLE user ( id_user INTEGER PRIMARY KEY AUTOINCREMENT, external_id INTEGER NOT NULL;") database.execSQL("INSERT INTO user ( id_user, external_id ) " + " SELECT id_user, external_id" + " FROM user_old;") database.execSQL("CREATE UNIQUE INDEX idx_unique_user ON user (external_id);") database.execSQL("PRAGMA foreign_keys=on;") database.execSQL("DROP TABLE user_old;") //database.endTransaction() }
quelle
@Database(entities = {Tablename1.class, Tablename2.class}, version = 3, exportSchema = false)
Ändern Sie die Versionsnummer in Ihrer RoomDatabase-Klasse. Erhöhen Sie die Versionsnummer.
quelle
Wenn das Erhöhen der Schemaversion bei Ihnen nicht funktioniert hat, stellen Sie die Migration Ihrer Datenbank bereit. Dazu müssen Sie die Migration im Datenbank-Builder deklarieren:
Room.databaseBuilder(context, RepoDatabase.class, DB_NAME) .addMigrations(FROM_1_TO_2) .build(); static final Migration FROM_1_TO_2 = new Migration(1, 2) { @Override public void migrate(final SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE Repo ADD COLUMN createdAt TEXT"); } };
quelle
Ich hatte gerade ein ähnliches Problem in einem Espresso-Test und das einzige, was es behoben hat, war das Löschen von Daten und auch das Deinstallieren der AndroidX-Test-Apks wie:
adb uninstall androidx.test.orchestrator adb uninstall androidx.test.services
quelle
In meinem Fall habe ich ein Update für eine Datenbank vorgenommen, die ich mit meiner App vorverpacken werde. Keiner der Vorschläge hier hat funktioniert. Aber ich habe endlich herausgefunden, dass ich die .db-Datei in einem Datenbankprogramm öffnen kann (ich habe "DB Browser for SQLite" verwendet) und die "Benutzerversion" manuell von 2 zurück auf 1 ändern kann. Danach hat es perfekt funktioniert.
Ich denke, jedes Update, das Sie an dieser Benutzerversion vornehmen, und aus diesem Grund wurde dieser Fehler immer wieder angezeigt.
quelle
In meinem Fall habe ich alles versucht. Nichts schien zu funktionieren, daher bestand die Lösung für mich darin
android:allowBackup="false"
, die App einfach einzustellen, zu installieren und dann wieder auf true zu setzenHoffe es hilft anderen :)
quelle
Ich habe den gleichen Fehler während des Trainingsprogramms von Codelabs erhalten. Wo In einer Schulungssitzung habe ich ein Projekt erstellt, das mit allen Datenbankoperationen erfolgreich ausgeführt wurde. In der nächsten Sitzung arbeitete ich mit einem anderen Repo, aber es war eine Erweiterung des vorherigen Projekts. Vom ersten Build der erweiterten App an hatte nur ich den Fehler erhalten.
quelle