Комната не может проверить целостность данных

Я получаю эту ошибку при запуске программы с базой данных номеров

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.

Кажется, нам нужно обновить версию базы данных, но откуда мы можем это сделать в комнате?


person Ravi    schedule 26.05.2017    source источник
comment
Если вам не важны данные приложения, удаление всего содержимого из настроек приложения также может помочь, поскольку оно просто уничтожает всю БД.   -  person O-9    schedule 24.04.2019


Ответы (20)


Когда вы впервые столкнетесь с этим сообщением, скорее всего, вы работаете с невыпущенной версией базы данных. В этом случае скорее всего, вам не следует увеличивать версию базы данных. Простая очистка данных приложения переместит вас в исключение.

Если вы не увеличиваете базу данных (рекомендуется):

Вам следует очистить данные приложения в настройках Android. В качестве альтернативы вы можете удалить предыдущую версию приложения, а затем установить новую версию, чтобы передать исключение. Последний подход не работает при определенных условиях (например, когда разрешено резервное копирование).

Поскольку очистка данных приложения всегда работает, я каждый раз выбираю этот путь.

Если вы увеличиваете версию базы данных:

Вам нужно будет написать код миграции базы данных, чтобы учесть любые изменения в схеме базы данных. См. здесь для получения информации о миграции.

Альтернативой написанию кода миграции базы данных является вызов fallbackToDestructiveMigration в построителе базы данных Room. Вероятно, это не лучшая идея. Если вы забудете удалить этот вызов, а затем забудете обновить базу данных, это приведет к потере данных.

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

Опять же, ни увеличение версии базы данных, ни возврат к деструктивной миграции не требуется, если предыдущая схема базы данных не является действующей в дикой природе.

person methodsignature    schedule 30.08.2017
comment
Я бы хотел, чтобы они добавили еще один резервный метод для этого случая :( - person BoD; 20.09.2017
comment
В версии 1.0.0-rc1 Room единственное, что у меня работало, - это увеличение версии базы данных. - person Dick Lucas; 31.10.2017
comment
У меня был android: allowBackup = true в моем AndroidManifest.xml, который не позволял очистить данные даже после удаления приложения. Я установил для этого атрибута значение false, а затем переустановил приложение, что помогло избавиться от проблемы. Обратите внимание, что true - это значение по умолчанию для allowBackup, поэтому, если вы его вообще не используете, это может привести к сохранению данных. - person Bartek; 21.12.2017
comment
@Bartek, этот комментарий теперь заслуживает ответа. - person guness; 04.01.2018
comment
Такое объяснение! Я снова и снова удалял приложение, потому что зачем обновлять разрабатываемую версию? О боже, никогда не думал, что очистка данных из настроек - ключ к успеху. Хороший ответ. Должно быть приемлемое решение. - person sud007; 28.02.2019
comment
Спасибо, что действительно подумали об этом, прежде чем просто предложить увеличить число. Я знал, что это не может быть правильным путем, когда еще разрабатывал приложение. - person Big_Chair; 15.05.2019
comment
Этот ответ - чистое золото. четкие данные отлично работали для меня, я удалял и устанавливал снова, но все еще получаю сообщение об ошибке. Кроме того, дополнительная информация потрясающая. - person A.Alqadomi; 19.11.2019
comment
У меня сработало удаление приложения, спасибо! - person Mehdi Fracso; 30.12.2020

По умолчанию в манифесте Android есть android:allowBackup="true", что позволяет приложениям сохранять свою базу данных SQLite при переустановке.

Предположим, что ваш DATABASE_VERSION изначально был 3, а затем вы решили уменьшить версию БД с 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.
//        }
//    };
}

Вы можете добиться этого так

  • Удалите данные приложения из настроек. Это удалит старую БД (DATABASE_VERSION = 3) с телефона
  • Удалите ваше приложение
  • Уменьшите версию DATABASE_VERSION до 1
  • Создайте и переустановите свое приложение

Хорошая практика - поддерживать постоянное значение DATABASE_VERSION.

person Hitesh Sahu    schedule 17.01.2018
comment
Не повлияет ли это на пользователей, которые будут обновлять приложение из игрового магазина? - person nimi0112; 04.03.2019
comment
Я пошел по тому же пути, но не сработало. Даже я пытаюсь установить новое устройство из Android Studio, он показывает ту же ошибку: x - person Sadat; 30.04.2019
comment
@ nimi0112 Для вашего варианта выпуска вы должны разрешить резервное копирование, однако для вашего варианта отладки вы можете отключить его - person Chad Mx; 25.12.2019

android: allowBackup = "true" внутри AndroidManifest.xml предотвращает очистку данных даже после удаления приложения.

Добавьте это в свой манифест:

android:allowBackup="false"

и переустановите приложение.

Примечание. Убедитесь, что вы изменили его обратно на true позже, если хотите автоматическое резервное копирование.

Другое решение:

Проверьте identityHash своего старого файла json и нового файла json в папке apps \ schema.

Если 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.");
    }
}
person live-love    schedule 17.11.2018

Ответ Анируддх Парихар дал мне подсказку, и он решил.

Найдите класс, в котором вы расширили RoomDatabase. Там вы найдете версию, подобную приведенной ниже:

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

просто увеличьте версию и проблема решена.

person Ravi    schedule 26.05.2017

Это очень просто, как показано в журнале

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 по сравнению с текущей.

Например: найдите аннотацию @Database в своем проекте, как показано ниже.

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

Здесь версия = 1, это версия базы данных, вам нужно просто увеличить ее на единицу, и все.

person Aniruddh Parihar    schedule 26.05.2017
comment
Да, я получил эту ошибку, поэтому я также упомянул, что It seems we need to update database version. Но я не понимал, где упоминалась эта версия. В любом случае спасибо за этот намек. - person Ravi; 26.05.2017
comment
Вы изменили формулировку сообщения об ошибке, но не предоставили никакой дополнительной информации, чтобы устранить путаницу в исходном плакате. - person Carl Rossman; 15.11.2020
comment
@CarlRossman: вы должны найти свой класс базы данных в своем проекте, где вы использовали аннотацию базы данных, в этом классе вы найдете версию базы данных (целочисленное значение), просто увеличьте ее на единицу от текущей. - person Aniruddh Parihar; 15.11.2020

1: - Похоже, нам нужно обновить версию базы данных (увеличить на 1)

введите описание изображения здесь

2-й Удалите приложение или очистите данные приложения

person Keshav Gera    schedule 03.09.2019

Не используйте это решение в производственном коде!
Используйте ответ Анируддха Парихара или ответ peterzinho16 вместо этого!

На телефоне Android:

Удалите приложение или Очистите данные приложения.

Чтобы удалить данные приложения: Настройки Go - ›Приложения -› Выберите приложение - ›Хранилище -› Очистить данные

Удаление (и повторная установка) работает не во всех случаях, поэтому сначала попробуйте очистить данные!

person Marci    schedule 14.08.2019
comment
Да, это сработало. Но, как ни странно, у меня возникла эта проблема на устройстве, которое было полностью стерто и настроено только что. Но простая очистка данных решена. - person Ajith Memana; 06.05.2020
comment
Этого не следует делать на производстве. Вы не должны заставлять всех своих пользователей удалять данные из приложения. Лучше написать код миграции, увеличив версию на 1 в базе данных Room. - person Rajeev Jayaswal; 31.07.2020
comment
Как уже упоминал @RajeevJayaswal, это ужасная идея даже для целей тестирования. Вместо этого вам следует использовать вариант миграции. - person Mbuodile Obiosio; 27.04.2021

Чтобы исправить проблему в котлине:

Первый

@Database(entities = [Contact::class], version = 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()

Дополнительные сведения см. В официальной документации.

person peterzinho16    schedule 09.04.2020
comment
Хорошее объяснение, спасибо - person AlexPes; 27.04.2021

В моем случае android:allowBackup="false" преобразование его из истинного в ложное сработало, поскольку это и раньше вызывало у меня кошмары, это самая странная вещь, почему этот параметр включен по умолчанию!

person Divyanshu Negi    schedule 24.03.2019

Эта проблема чаще всего возникает в процессе разработки.

Если вы измените свою схему, то есть переименуете / добавите / измените свой класс, содержащий объект таблицы, целостность между выходом из базы данных в вашей предыдущей сборке конфликтует с новой сборкой.

очистите данные приложения или установите новую сборку после удаления предыдущей сборки.

Теперь старый db не будет конфликтовать с новым.

person Extremis II    schedule 19.08.2018
comment
После этого все еще сбой - person user7856586; 26.11.2018
comment
какое исключение? пожалуйста, поднимите журнал, чтобы сузить круг вопросов. - person Extremis II; 26.11.2018
comment
Спасибо, теперь все ок. Я читал про android:allowBackup="true" и использую его с умом - person user7856586; 26.11.2018
comment
@ user7856586 Так что насчет allowBackup? Не могли бы вы просветить нас своей мудростью? - person Ridcully; 24.12.2018
comment
@Ridcully, ты можешь прочитать об этом здесь Почему ты так зол? - person user7856586; 24.12.2018
comment
Спасибо! Зайдите в Настройки ›Приложения› [Имя приложения] ›Хранилище› Очистить хранилище у меня сработало! - person Dan; 06.02.2019

В моем случае я использовал транзакцию внутри миграции, и 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() 
}
person JARP    schedule 18.04.2018
comment
Я борюсь несколько часов, и это было решением !! Спасибо!! - person Javier; 14.06.2018
comment
В приведенном выше примере проблема не в транзакции. Вы забыли установить успешную транзакцию перед ее завершением: ‹pre› ‹code› database.beginTransaction () database.setTransactionSuccessful () database.endTransaction () ‹/code› ‹/pre› - person birukoff; 08.01.2019

В моем случае у меня был класс AppDatabase.

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

Я обновил этот номер версии, и проблема была решена. Проблема возникла из-за того, что я добавил свойство в класс SongInfo и забыл обновить номер версии.

Надеюсь, это кому-то поможет.

person Harry .Naeem    schedule 21.07.2018

Если вы обновляете версию 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

В комнате Новая версия 1.0.0-alpha9 В комнате добавлена ​​поддержка ограничения NOT NULL.

Это изменит схему, которую генерирует Room. Поскольку он изменяет схему, он также изменяет identityHash БД, который используется Room для однозначной идентификации каждой версии БД. Следовательно, нам нужна миграция

person Bhargav Pandya    schedule 31.08.2017

В моем случае ContentProvider и база данных комнаты работают вместе, поэтому сначала удалите все обратные вызовы ContentProvider по всему приложению с классом базы данных, который расширяет класс SqlLiteOpenHelper

person chaman    schedule 06.04.2018

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

Измените номер версии в своем классе RoomDatabase. Увеличьте номер версии.

person Rajeev Shetty    schedule 06.11.2019

Если увеличивающаяся версия схемы у вас не сработала, обеспечьте миграцию вашей базы данных. Для этого вам нужно объявить миграцию в построителе базы данных:

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");
    }
};
person Hagar Magdy    schedule 24.11.2019
comment
Да, это правильный путь - person Bipin Bharti; 21.02.2020

У меня была аналогичная проблема в тесте эспрессо, и единственное, что исправило это, - это очистка данных, а также удаление тестовых apks androidx, например:

adb uninstall androidx.test.orchestrator
adb uninstall androidx.test.services
person Daniel Jonker    schedule 29.07.2019

В моем случае я обновлял базу данных, которую я буду предварительно упаковывать вместе со своим приложением. Ни одно из предложений здесь не сработало. Но я наконец понял, что могу открыть файл .db в программе базы данных (я использовал «Браузер БД для SQLite») и вручную изменить «Пользовательскую версию» с 2 на 1. После этого все заработало отлично.

Я предполагаю, что любое обновление, которое вы вносите, изменяет эту пользовательскую версию, и именно поэтому я продолжал получать эту ошибку.

person Gavin Wright    schedule 25.03.2020
comment
Можете ли вы помочь мне с тем же? Я не могу найти версию в браузере БД для SQLite - person GreenROBO; 20.06.2020
comment
Он находится на вкладке Edit pragmas. Это называется пользовательской версией. - person Gavin Wright; 21.06.2020
comment
да. Я понял. Спасибо за помощь Гэвину :) - person GreenROBO; 22.06.2020

Быстрое решение

Перейдите в класс AddDatabase и увеличьте версию своей базы данных

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(entities = arrayOf(Product::class, SatisNok::class), version = 6)
abstract class AppDatabase : RoomDatabase() {
    abstract fun productDao(): ProductDao
    abstract fun satisDao(): SatisNokDao
}

Зайдите в Activity или позвоните своему db

добавили способ миграции, вот поменял версию с 5 на 6

  val MIGRATION_1_2: Migration = object : Migration(5,6) {
            override fun migrate(database: SupportSQLiteDatabase) {
                // Since we didn't alter the table, there's nothing else to do here.
            }
        }

Теперь добавьте дополнение миграции в ваш builder базы данных как .addMigrations(MIGRATION_1_2)

 val db = Room.databaseBuilder(
                applicationContext,
                AppDatabase::class.java, "supervisor"
            ).fallbackToDestructiveMigration()
                .allowMainThreadQueries()
                .addMigrations(MIGRATION_1_2)
                .build()

Для получения дополнительных сведений посетите здесь, где все усложняется. день за днем, где они должны обеспечивать более легкие растворения.

после операции вы можете прокомментировать строку //.addMigrations(MIGRATION

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(entities = arrayOf(Product::class, SatisNok::class), version = 6)
abstract class AppDatabase : RoomDatabase() {
    abstract fun productDao(): ProductDao
    abstract fun satisDao(): SatisNokDao
}
2) и оставить ее до следующего раза

person Sam    schedule 07.04.2021

У меня такая же ошибка возникла во время программы обучения Codelabs. Где В одном учебном занятии я создал проект, и он успешно выполнил все операции с базой данных. В следующем сеансе я работал с другим репо, но это было расширением предыдущего проекта. Только из первой сборки расширенного приложения я получил ошибку.

Возможно, Studio сохраняет методы аутентификации с базой данных комнат, которые отсутствуют в новой сборке.

person Willey Hute    schedule 12.12.2019