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


105

Room Databaseでプログラムを実行しているときに、このエラーが発生します

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のどこから更新できますか?


2
それだけで全体のDBを破壊するので、あなたは、アプリケーションの設定からすべてのコンテンツを削除すると、ヘルプもかもしれませんが、アプリのデータを気にしない場合
O-9

回答:


142

このメッセージに最初に出くわしたときは、リリースされていないバージョンのデータベースに対して作業している可能性があります。その場合は、データベースのバージョンをインクリメントしないでください。アプリのデータをクリアするだけで、例外を通過したことになります。

データベースをインクリメントしない場合(推奨):

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

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

データベースのバージョンをインクリメントする場合:

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

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

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

以前のデータベーススキーマがライブでない場合は、再度、どちらもデータベースのバージョンをインクリメントしたり破壊的な移行に戻って落下することは必要ありません野生で


4
この場合の別のフォールバック方法が含まれているといいのですが:(
BoD 2017

3
1.0.0-rc1Roomのバージョンでは、データベースのバージョンをインクリメントするだけでうまくいきました。
ディックルーカス

44
AndroidManifest.xmlにandroid:allowBackup = "true"があり、アプリをアンインストールした後でもデータがクリアされませんでした。この属性をfalseに設定してからアプリを再インストールしました。これにより、問題を解決できました。trueはallowBackupのデフォルト値であるため、まったく使用しない場合でも、データが保持される可能性があることに注意してください。
Bartek 2017

1
@Bartekこのコメントは今や答えに値する。
ガネス

そんな説明!開発中のバージョンをアップグレードする理由のために、アプリを何度もアンインストールしていました。おやおや、設定からデータをクリアすることが重要だとは思わなかった。いい答えだ。受け入れられた解決策である必要があります。
sud0 0719

31

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

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一定に保つことは良い習慣です。


1
Playストアからアプリを更新するユーザーには影響しませんか?
nimi01 1219年

1
私は同じ方法に従いましたが、うまくいきませんでした。でも私は、Android Studioからの新鮮なデバイスにインストールしようとしています、それは同じエラーを示しています。x
サダト

@ nimi0112リリースバリアントの場合はバックアップを許可する必要がありますが、デバッグバリアントの場合はオフにすることができます
ChadMx19年

27

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

20

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

拡張したクラスを検索しますRoomDatabase。そこにあなたは以下のようなバージョンを見つけるでしょう:

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

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


12

ログに示されているように、その非常に単純です

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

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

例:以下のようにプロジェクトで@Databaseアノテーションを検索します

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

ここでバージョン= 1はデータベースバージョンです。1つ増やすだけです。それだけです。


1
はい、私はそのエラーを受け取りました、それは私が問題にそれも言及した理由ですIt seems we need to update database version。しかし、私はそのバージョンが言及された場所を取得していませんでした。とにかくそのヒントをありがとう。
ラビ2017年

エラーメッセージを言い換えましたが、元の投稿者の混乱に対処するための追加情報を提供していません。
カールロスマン

@CarlRossman:データベースアノテーションを使用したプロジェクトでデータベースクラスを見つける必要があります。そのクラスにはデータベースバージョン(整数値)があり、現在から1つ増やします。
AniruddhParihar20年

7

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

ここに画像の説明を入力してください

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


6

Android携帯の場合:

アプリをアンインストールする、アプリデータを消去します

アプリデータを削除するには:[設定]-> [アプリ]-> [アプリを選択]-> [ストレージ]-> [データを消去]に移動します

アンインストール(および再インストール)がすべての場合に機能するとは限らないため、最初にデータをクリアしてみてください。


はい、うまくいきました。しかし不思議なことに、私はこの問題を完全に消去してセットアップを新しくしたデバイスで発生していました。しかし、単に解決されたデータをクリアするだけです。
AjithMemana20年

これは本番環境では実行しないでください。すべてのユーザーにアプリからデータを消去するように強制しないでください。Roomデータベースのバージョンを1増やして、移行コードを作成することをお勧めします。
RajeevJayaswal20年

5

私の場合android:allowBackup="false"、これをtrueからfalseに変更すると、以前にも悪夢が発生したため、この設定がデフォルトで有効になっているのは最も奇妙なことです。


5

kotlinの問題を修正するには:

最初

@Database(entities = [Contact::class], version = 2)

2番目

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 ''")
        }
    }

三番

private fun buildDatabase(context: Context) = Room.databaseBuilder(
            context.applicationContext,
            EpayDatabase::class.java,
            "epay"
        )
            .addMigrations(MIGRATION_1_2)
            .build()

詳細については、公式ドキュメントを確認してください


4

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

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

アプリのデータを消去したり、以前のビルドをアンインストールした後に新しいビルドをインストール

これで、古いデータベースが新しいデータベースと競合することはありません。


その後もクラッシュします
user7856586 2018年

例外は何ですか?問題を絞り込むためにログを作成してください。
ExtremisII18年

2
おかげで、今はすべて大丈夫です。私android:allowBackup="true"はそれについて読み、賢く使用します
user7856586 2018年

1
@ user7856586では、allowBackupはどうですか?あなたの知恵で私たちを啓発していただけませんか?
ばかげて2018

@Ridcullyあなたはここでそれについて読むことができます なぜあなたはとても怒っているのですか?
user7856586 2018

3

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

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

私は数時間苦労しました、そしてこれが解決策でした!ありがとうございました!!
ハビエル

1
上記の例では、問題となるのはトランザクションではありません。あなたはそれを終了する前に、設定されたトランザクションの成功に忘れてしまった:<PRE>の<code> database.beginTransaction()database.setTransactionSuccessful()database.endTransaction()</ code>を</ PRE>
birukoff

3

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

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

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

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


2

Roomバージョンを古いバージョンから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

Roomの新しいバージョン1.0.0-alpha9Roomでは、NOTNULL制約のサポートが追加されています。

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


2

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


2
@Database(entities = {Tablename1.class, Tablename2.class}, version = 3, exportSchema = false)

RoomDatabaseクラスのバージョン番号を変更します。バージョン番号をインクリメントします。


2

スキーマバージョンの増加がうまくいかなかった場合は、データベースの移行を提供してください。これを行うには、データベースビルダーで移行を宣言する必要があります。

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");
    }
};

はい、これは適切な方法です
BipinBharti20年

1

私はエスプレッソテストで同様の問題を抱えていましたが、それを修正した唯一のことは、データをクリアし、次のようなandroidxテストapkをアンインストールすることでした:

adb uninstall androidx.test.orchestrator
adb uninstall androidx.test.services

0

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

それが他の人に役立つことを願っています:)


1
これはまさに私が答えたものです、なぜ答えを繰り返すのですか?
DivyanshuNegi19年

0

私の場合、アプリで事前にパッケージ化するデータベースを更新していました。ここでの提案はどれもうまくいきませんでした。しかし、データベースプログラムで.dbファイルを開いて(「DBBrowser for SQLite」を使用)、手動で「ユーザーバージョン」を2から1に戻すことができることがようやくわかりました。その後、完全に機能しました。

更新すると、このユーザーバージョンが変更されると思います。そのため、このエラーが発生し続けました。


同じことを手伝ってくれませんか。私はSQLiteのためのDBブラウザでバージョンを見つけることができません
GreenROBO

[プラグマの編集]タブの下にあります。それは「ユーザーバージョン」と呼ばれます。
ギャビン・ライト

はい。わかった。ヘルプギャビンてくれてありがとう:)
GreenROBO

-2

Codelabsのトレーニングプログラム中に同じエラーが発生しました。1つのトレーニングセッションでプロジェクトを作成し、すべてのデータベース操作で正常に実行されました。次のセッションでは、別のリポジトリで作業していましたが、それは前のプロジェクトの拡張でした。拡張アプリの最初のビルドから、エラーが発生しただけでした。

たぶんStudioは、新しいビルドでは欠落しているルームデータベースで認証技術を維持しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.