web-dev-qa-db-ja.com

部屋はデータの整合性を検証できません

ルームデータベースでプログラムを実行しているときにこのエラーが発生します

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.

データベースのバージョンを更新する必要があるようですが、どこからRoomでそれを行うことができますか?

47
Ravi Rupareliya

このメッセージに最初に出くわしたときは、データベースの未リリースバージョンに対して作業している可能性が高いでしょう。その場合、ほとんどの場合、データベースのバージョンをインクリメントしないでください。アプリのデータを消去するだけで、例外に合格します。

データベースを増分しない場合(推奨):

Android設定からアプリケーションのアプリデータを消去する必要があります。または、以前のアプリバージョンをアンインストールしてから、新しいバージョンをインストールして例外を渡すこともできます。この後者のアプローチは、特定の条件下では機能しません(バックアップを許可する場合など)

アプリケーションデータのクリアは常に機能するため、毎回そのルートを取ります。

データベースのバージョンを増やす場合:

データベーススキーマへの変更を考慮して、データベース移行コードを記述する必要があります。移行については here をご覧ください。

データベース移行コードを記述する代わりに、RoomデータベースビルダーでfallbackToDestructiveMigrationを呼び出すこともできます。これはおそらく良い考えではありません。この呼び出しを削除し忘れて、データベースのアップグレードを忘れると、データが失われます。

// Using this fallback is almost certainly a bad idea
Database database = Room.databaseBuilder(context, Database.class, DATABASE_NAME)
        .fallbackToDestructiveMigration()
        .build();

繰り返しますが、以前のデータベーススキーマがライブに存在しない場合、データベースバージョンをインクリメントしたり、破壊的な移行にフォールバックする必要はありません。

78
methodsignature

デフォルトでは、AndroidマニフェストにはAndroid:allowBackup="true"があり、これによりアプリは再インストール時にSQLite DBを保持できます。

DATABASE_VERSIONが最初は3だった場合、DBバージョンを3から1に減らすことにします。

@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.
//        }
//    };
}

このように達成できます

  • 設定からアプリのデータを消去します。これにより、古いDB(DATABASE_VERSION = 3)が電話から削除されます
  • アプリをアンインストールする
  • DATABASE_VERSIONバージョンを1に減らします
  • アプリをビルドして再インストールする

DATABASE_VERSIONを一定に保つことをお勧めします。

14
Hitesh Sahu

ログに示されているように、その非常にシンプルな

Looks like you've changed schema but forgot to update the version number. 
You can simply fix this by increasing the version number.

データベースクラスに移動し、現在のバージョンから1を増やしてDBバージョンをアップグレードします。

11

Aniruddh Parihar の答えは私にヒントを与え、解決しました。

RoomDatabaseを拡張したクラスを検索します。そこには以下のようなバージョンがあります:

@Database(entities = {YourEntity.class}, version = 1)

バージョンを上げるだけで問題は解決します。

9
Ravi Rupareliya

AndroidManifest.xml内のAndroid:allowBackup = "true"は、アプリがアンインストールされた後でもデータが消去されないようにします。

これをマニフェストに追加します。

Android:allowBackup="false"

アプリを再インストールします。

注:自動バックアップが必要な場合は、後でそれをtrueに戻してください。

別のソリューション:

Apps\schemaフォルダーにある古いjsonファイルと新しいjsonファイルのidentityHashを確認します。

IdentityHashが異なる場合、そのエラーが発生します。何も変更したくない場合は、両方のjsonファイルを比較して、変更内容を確認します。

ExportSchema = trueであることを確認してください。

@Database(entities = {MyEntity.class, ...}, version = 2, exportSchema = true)

jsonスキーマファイル:

  "formatVersion": 1,
  "database": {
    "version": 2,
    "identityHash": "53cc5ef34d2ebd33c8518d79d27ed012",
    "entities": [
      {

コード:

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.");
    }
}
5
live-love

この問題は主に開発時に発生します。

スキーマを変更する場合、つまり、テーブルエンティティを含むクラスの名前を変更/追加/変更すると、以前のビルドで終了したdb間の整合性が新しいビルドと競合します。

アプリのデータを消去するまたは前のビルドをアンインストールした後に新しいビルドをインストールする

現在、古いデータベースは新しいデータベースと競合しません。

4
sudesh

私の場合、Android:allowBackup="false"がtrueからfalseに機能するようになりました。これは以前にも悪夢をもたらしたので、これがこの設定がデフォルトで有効になっている最も奇妙なことです!

4
Divyanshu Negi

私の場合、AppDatabaseクラスがありました。

@Database(entities = {GenreData.class, MoodData.class, SongInfo.class,
    AlbumsInfo.class, UserFolderListsData.class, UserPlaylistResponse.PlayLists.class, InternetConnectionModel.class}, version = 3, exportSchema = false)

このバージョン番号を更新し、問題を解決しました。 SongInfoクラスにプロパティを追加し、バージョン番号を更新するのを忘れていたため、問題が発生しました。

それが誰かを助けることを願っています。

3
Harry .Naeem

Android電話:

アプリのアンインストールまたはアプリデータのクリア

アプリのデータを削除するには:設定->アプリ->アプリを選択->ストレージ->データを消去

アンインストール(および再インストール)はすべての場合に機能するわけではないため、データをクリアしてみてください!

2
Marci

ルームバージョンを古いバージョンから1.0.0-alpha9にアップグレードする場合は、以下の記事をご覧ください。古いバージョンから1.0.0-alpha9バージョンへの移行に関する非常に良い記事。

https://medium.com/@manuelvicnt/Android-room-upgrading-alpha-versions-needs-a-migration-with-kotlin-or-nonnull-7a2d140f05b9

ルームの新しいバージョン1.0.0-alpha9ルームでは、NOT NULL制約のサポートが追加されています。

これにより、Roomが生成するスキーマが変更されます。スキーマを変更するため、DBのidentityHashも変更され、RoomがすべてのDBバージョンを一意に識別するために使用されます。したがって、移行が必要です

2
Bhargav Pandya

私の場合、移行内でトランザクションを使用していましたが、ルームは移行ヘルパーを使用してハッシュを更新できませんでした

@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() 
}
2
JARP

私の場合、ContentProviderとルームデータベースは連携して動作するため、最初にSqlLiteOpenHelperクラスを拡張するデータベースクラスを使用して、アプリケーション全体のContentProviderのすべてのコールバックを削除します

2
chaman

1:-データベースのバージョンを更新する必要があるようです(1ずつ増加)

enter image description here

2番目アプリのアンインストールまたはアプリデータの消去

0
Keshav Gera

エスプレッソテストでも同様の問題が発生しましたが、それを修正したのは、データをクリアし、次のようなandroidxテストapkをアンインストールすることだけでした:

adb uninstall androidx.test.orchestrator
adb uninstall androidx.test.services
0
Daniel Jonker

私の場合、上記のすべてを試しました。何も機能していないように思えたので、私にとっての解決策は、単にAndroid:allowBackup="false"を設定し、アプリをインストールしてからtrueに戻すことでした。

それが他の人を助けることを願っています:)

0
gmartinsnull