कक्ष डेटा अखंडता को सत्यापित नहीं कर सकता है


105

कक्ष डेटाबेस के साथ कार्यक्रम चलाते समय मुझे यह त्रुटि हो रही है

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.

ऐसा लगता है कि हमें डेटाबेस संस्करण को अपडेट करने की आवश्यकता है, लेकिन हम उस कमरे में कहां से कर सकते हैं?


2
यदि आप ऐप के डेटा के बारे में परवाह नहीं करते हैं, तो एप्लिकेशन सेटिंग्स से सभी सामग्री को हटाने में भी मदद मिल सकती है, क्योंकि यह पूरे डीबी को नष्ट कर देता है
O-9

जवाबों:


142

जब आप पहली बार इस संदेश पर आते हैं, तो आप सबसे अधिक संभावना डेटाबेस के एक अप्रबंधित संस्करण के खिलाफ काम करेंगे। यदि ऐसा है, तो सबसे अधिक संभावना है कि आपको डेटाबेस संस्करण में वृद्धि नहीं करनी चाहिए । बस क्लीयरिंग ऐप डेटा आपको स्थानांतरित कर देगा अपवाद को पार कर जाएगा।

यदि आप डेटाबेस में वृद्धि नहीं करते हैं (अनुशंसित):

आपको एंड्रॉइड सेटिंग्स से एप्लिकेशन के एप्लिकेशन डेटा को साफ़ करना चाहिए। आप वैकल्पिक रूप से पिछले एप्लिकेशन संस्करण की स्थापना रद्द कर सकते हैं और फिर अपवाद को प्राप्त करने के लिए नया संस्करण स्थापित कर सकते हैं। यह बाद वाला दृष्टिकोण कुछ शर्तों के तहत काम नहीं करता है (जैसे कि जब बैकअप सक्षम हो तो)

चूंकि एप्लिकेशन डेटा क्लियर करना हमेशा काम करता है, इसलिए मैं हर बार उस रूट को लेता हूं।

यदि आप डेटाबेस संस्करण में वृद्धि करते हैं:

डेटाबेस स्कीमा में किसी भी बदलाव के लिए आपको डेटाबेस माइग्रेशन कोड लिखना होगा। माइग्रेशन के बारे में जानकारी के लिए यहां देखें ।

डेटाबेस माइग्रेशन कोड लिखने का विकल्प fallbackToDestructiveMigrationरूम डेटाबेस बिल्डर को कॉल करना है। यह शायद एक अच्छा विचार नहीं है। इस कॉल को हटाने और फिर डेटाबेस को अपग्रेड करने के लिए भूल जाने से डेटा की हानि होगी।

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

फिर से, न तो डेटाबेस संस्करण को बढ़ाना और न ही विनाशकारी प्रवास पर वापस जाना आवश्यक है यदि पिछले डेटाबेस स्कीमा जंगल में नहीं रहता है


4
काश वे इस मामले के लिए एक और पतन विधि शामिल करेंगे :(
बोद

3
1.0.0-rc1कक्ष के संस्करण में केवल एक चीज जो मेरे लिए काम करती थी, वह डेटाबेस संस्करण को बढ़ाना था।
डिक लुकास

44
मेरे पास Android: allowBackup = "true" मेरे AndroidManifest.xml में था, जिसने ऐप को अनइंस्टॉल करने के बाद भी डेटा को क्लियर होने से रोक दिया था। मैंने इस विशेषता को झूठे पर सेट किया और फिर ऐप को पुनः इंस्टॉल किया, जिससे समस्या से छुटकारा पाने में मदद मिली। ध्यान दें कि सही है allowBackup के लिए डिफ़ॉल्ट मान, इसलिए यदि आप इसका उपयोग बिल्कुल नहीं करते हैं, तो यह अभी भी डेटा को बनाए रखने का कारण हो सकता है।
Bartek

1
@Bartek की यह टिप्पणी अब जवाब देने लायक है।
बन्दूक

ऐसी व्याख्या! मैं बार-बार ऐप को अनइंस्टॉल कर रहा था क्योंकि विकास में संस्करण को क्यों अपग्रेड किया जाए? अरे लड़का, यह कभी नहीं सोचा था कि सेटिंग्स से डेटा साफ़ करना आगे की कुंजी है। अच्छा उत्तर। स्वीकृत समाधान होना चाहिए।
सूद ०7

31

डिफ़ॉल्ट रूप से एंड्रॉइड मैनिफ़ेस्ट होता है 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स्थिर रखने के लिए यह एक अच्छा अभ्यास है ।


1
क्या यह उन उपयोगकर्ताओं को प्रभावित नहीं करेगा जो ऐप को प्ले स्टोर से अपडेट करेंगे?
nimi0112

1
मैंने उसी तरह से पालन किया है, लेकिन काम नहीं किया। यहां तक ​​कि मैं एंड्रॉइड स्टूडियो से एक ताजा डिवाइस पर स्थापित करने की कोशिश कर रहा हूं, यह एक ही त्रुटि दिखाता है: x
सआदत

@ nimi0112 आपके रिलीज़ संस्करण के लिए, आपको बैकअप की अनुमति देनी चाहिए, हालाँकि आपके डिबग संस्करण के लिए, आप इसे बंद कर सकते हैं
चाड Mx

27

Android: allowBackup = "true" AndroidManifest.xml के अंदर ऐप के अनइंस्टॉल होने के बाद भी डेटा को क्लियर होने से रोकता है।

इसे अपनी अभिव्यक्ति में जोड़ें:

android:allowBackup="false"

और एप्लिकेशन को पुनर्स्थापित करें।

नोट: सुनिश्चित करें कि यदि आप ऑटो बैकअप चाहते हैं तो आप इसे बाद में सही में बदल दें।

एक और समाधान:

अपने पुराने जोंस फाइल की पहचान और एप्स / स्कीमा फोल्डर में नए जोंस फाइल को देखें।

यदि पहचान अलग है, तो वह त्रुटि देगा। यदि आप कुछ भी बदलना नहीं चाहते हैं, तो दोनों 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

अनिरुद्ध परिहार के जवाब ने मुझे संकेत दिया और यह हल हो गया।

उस वर्ग की खोज करें जहाँ आपने विस्तार किया है 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(entities = {YourEntityName.class}, version = 1)

यहाँ संस्करण = 1, डेटाबेस संस्करण है, आपको इसे केवल एक, थाट से बढ़ाना होगा।


1
हाँ, मुझे वह त्रुटि मिली, इसीलिए मैंने प्रश्न में भी इसका उल्लेख किया है It seems we need to update database version। लेकिन मैं उस संस्करण का उल्लेख नहीं कर रहा था। वैसे भी उस संकेत के लिए धन्यवाद।
रवि

आपने त्रुटि संदेश पुनः प्राप्त कर लिया है लेकिन मूल पोस्टर भ्रम को दूर करने के लिए कोई अतिरिक्त जानकारी नहीं दी है।
कार्ल रौसमैन

@CarlRossman: आपको अपनी परियोजना में अपना डेटाबेस वर्ग मिला है जहाँ आपने डेटाबेस एनोटेशन का उपयोग किया है, उस वर्ग पर आपको डेटाबेस संस्करण (पूर्णांक मूल्य) मिलेगा, बस इसे वर्तमान से एक करके बढ़ाएं।
अनिरुद्ध परिहार

7

1: - ऐसा लगता है कि हमें डेटाबेस संस्करण को अपडेट करने की आवश्यकता है (1 से वृद्धि)

यहां छवि विवरण दर्ज करें

2 ऐप को अनइंस्टॉल करें या ऐप डेटा साफ़ करें


6

Android फ़ोन पर:

ऐप या क्लियर ऐप डेटा को अनइंस्टॉल करें

एप्लिकेशन डेटा को हटाने के लिए: सेटिंग पर जाएं -> ऐप्स -> अपना ऐप चुनें -> स्टोरेज -> डेटा साफ़ करें

अनइंस्टॉल (और फिर से इंस्टॉल) हर मामले में काम नहीं करता है, इसलिए पहले स्पष्ट डेटा का प्रयास करें!


हाँ जो काम किया। लेकिन अजीब तरह से मैं एक डिवाइस पर इस मुद्दे को मिल रहा था जो पूरी तरह से मिट गया और अभी-अभी ताज़ा हुआ। लेकिन बस हल किए गए डेटा को साफ़ करना।
अजीत मेमन

यह उत्पादन पर नहीं किया जाना चाहिए। आपको अपने सभी उपयोगकर्ताओं को ऐप से डेटा साफ़ करने के लिए बाध्य नहीं करना चाहिए। अपने कक्ष डेटाबेस में 1 से संस्करण बढ़ाकर माइग्रेशन कोड लिखना बेहतर है।
राजीव जायसवाल

5

मेरे मामले android:allowBackup="false"में यह सच से गलत काम कर रहा है, क्योंकि इसने मुझे बुरे सपने दिए हैं, साथ ही, यह सबसे अजीब बात है कि यह सेटिंग डिफ़ॉल्ट रूप से सक्षम क्यों है!


5

कोटलिन में समस्या को ठीक करने के लिए:

प्रथम

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

अधिक जानकारी के लिए, आधिकारिक दस्तावेज देखें


4

यह समस्या ज्यादातर विकास में होती है।

यदि आप अपने स्कीमा को बदलते हैं, तो अपनी नई बिल्ड के साथ अपने पिछले बिल्ड संघर्षों में db से बाहर निकलने के बीच अपनी इकाई का नाम बदलें / जोड़ें / बदलें।

एप्लिकेशन डेटा को साफ़ करें या पिछले बिल्ड की स्थापना रद्द करने के बाद नया निर्माण स्थापित करें

अब, पुराने DB नए के साथ संघर्ष नहीं करेगा।


उसके बाद अभी भी दुर्घटनाग्रस्त है
user7856586

अपवाद क्या है? समस्या को कम करने के लिए लॉग इन करें।
एक्सट्रीमिस II

2
धन्यवाद, अब सब ठीक है। मैं इसके बारे में android:allowBackup="true"और बुद्धिमानी से उपयोग करता
हूं

1
@ user7856586 तो allowBackup के बारे में क्या? क्या आप हमें अपनी बुद्धिमत्ता से प्रसन्न कर सकते हैं?
रात्रि

@ अचानक आप इसके बारे में यहाँ पढ़ सकते हैं कि आप इतने गुस्से में क्यों हैं?
user7856586

3

मेरे मामले में मैं माइग्रेशन के अंदर लेनदेन का उपयोग कर रहा था और रूम माइग्रेशन हेल्पर का उपयोग करके हैश को अपडेट नहीं कर सकता था

@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>
birfoff

3

मेरे मामले में मेरे पास एक AppDatabase Class था।

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

मैंने इस संस्करण संख्या को अद्यतन किया और इसने समस्या को हल किया। समस्या इसलिए उत्पन्न हुई क्योंकि मैंने SongInfo वर्ग में एक संपत्ति जोड़ी थी और संस्करण संख्या को अपडेट करना भूल गया था।

आशा है कि यह किसी की मदद करता है।


2

यदि आप पुराने संस्करण से कमरा संस्करण को 1.0.0-अल्फा 9 में अपग्रेड कर रहे हैं, तो कृपया नीचे दिए गए लेख पर जाएं। पुराने संस्करण से 1.0.0-अल्फ़ा 9 संस्करण में माइग्रेट के लिए बहुत अच्छा लेख।

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

रूम न्यू वर्जन 1.0.0-अल्फा 9 में रूम नॉट नाल बाधा के लिए समर्थन जोड़ता है।

यह उस स्कीमा को बदलने जा रहा है जो कक्ष उत्पन्न करता है। क्योंकि यह स्कीमा को बदलता है, यह डीबी की पहचान को भी बदलता है और इसका उपयोग रूम द्वारा हर डीबी संस्करण की विशिष्ट पहचान के लिए किया जाता है। इसलिए, हमें एक प्रवास की आवश्यकता है


2

मेरे मामले में कन्टैंटप्रॉइडर और रूम डेटाबेस एक साथ काम करते हैं इसलिए सबसे पहले कंटेंटप्रॉइडर के सभी कॉलबैक को डेटाबेस क्लास के साथ आवेदन पर हटा दें, जो SqlLiteOpenHelper Class तक फैला हुआ है


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

हाँ यह उचित तरीका है
बिपिन भारती

1

मुझे एस्प्रेसो टेस्ट में बस इसी तरह का मुद्दा मिला था और केवल एक चीज जिसने इसे ठीक किया था वह था डेटा को साफ़ करना और एंड्रॉइड टेस्ट एप की तरह अनइंस्टॉल करना भी:

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

0

मेरे मामले में मैंने उपरोक्त सभी की कोशिश की। काम करने के लिए कुछ भी नहीं लग रहा था इसलिए मेरे लिए समाधान बस सेट कर रहा था android:allowBackup="false", ऐप इंस्टॉल करें फिर इसे सही पर सेट करें

आशा है कि यह दूसरों की मदद करता है :)


1
यह वही है जो मैंने उत्तर दिया है, उत्तर को क्यों दोहराएं?
दिव्यांशु नेगी

0

मेरे मामले में मैं एक डेटाबेस के लिए एक अपडेट कर रहा था जिसे मैं अपने ऐप के साथ प्री-पैकेजिंग करूंगा। यहां कोई भी सुझाव काम नहीं आया। लेकिन मुझे अंततः पता चला कि मैं एक डेटाबेस प्रोग्राम में .db फ़ाइल को खोल सकता हूं (मैंने "SQLite के लिए DB ब्राउज़र" का उपयोग किया था), और मैन्युअल रूप से "उपयोगकर्ता संस्करण" को 2 से 1 से बदल दें। इसके बाद, यह पूरी तरह से काम करता है।

मुझे लगता है कि आप इस उपयोगकर्ता संस्करण में कोई भी बदलाव करते हैं, और यही कारण है कि मुझे यह त्रुटि मिलती रही।


क्या आप मेरी मदद कर सकते हैं? मैं SQLite के लिए DB Browser में संस्करण खोजने में असमर्थ हूं
GreenROBO

यह "pragmas संपादित करें" टैब के अंतर्गत है। इसे "उपयोगकर्ता संस्करण" कहा जाता है।
गैविन राइट

हाँ। मैं समझ गया। मदद के लिए धन्यवाद गेविन :)
ग्रीनरो

-2

कोडेलैब्स के प्रशिक्षण कार्यक्रम के दौरान मुझे वही त्रुटि मिली। जहां एक प्रशिक्षण सत्र में मैंने एक परियोजना बनाई और यह सभी डेटाबेस संचालन के साथ सफलतापूर्वक चला। अगले सत्र में, मैं एक अलग रेपो के साथ काम कर रहा था, लेकिन यह पिछली परियोजना का एक विस्तार था, विस्तारित ऐप के पहले निर्माण से केवल मुझे त्रुटि मिली थी।

शायद स्टूडियो कमरे के डेटाबेस के साथ प्रमाणीकरण तकनीक रखता है जो नए बिल्ड के साथ गायब है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.