【问题标题】:Room cannot verify the data integrity when re open the appRoom 重新打开应用时无法验证数据完整性
【发布时间】:2020-09-13 00:02:46
【问题描述】:

我正在从Codelabs 学习如何使用 Room 现在我有两张桌子

当我从 Android Studio 运行时是正常的

但是当我关闭并重新打开应用程序时出现错误

java.lang.IllegalStateException: Room 无法验证数据完整性。看起来您已更改架构但忘记更新版本号。您可以通过增加版本号来解决此问题。

重新打开应用时出错,不是安装时

我正在尝试升级版本号,但我仍然收到错误

这是我的代码

@Database(entities = [Type::class], version = 3)
abstract class TypeRoomDb : RoomDatabase(){

    abstract fun typeDao() : TypeDao

    companion object{
        @Volatile
        private var INSTANCE : TypeRoomDb? = null

        fun getDataBase(
            context: Context,
            scope: CoroutineScope
        ): TypeRoomDb {
            return INSTANCE ?: synchronized(this){
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    TypeRoomDb::class.java,
                    Cons.DB_NAME
                )
                    .fallbackToDestructiveMigration()
                    .addCallback(TypeDbCallBack(scope))
                    .build()
                INSTANCE = instance

                instance
            }
        }

        private class TypeDbCallBack(
            private val scope: CoroutineScope
        ) : RoomDatabase.Callback(){
            override fun onOpen(db: SupportSQLiteDatabase) {
                super.onOpen(db)
                INSTANCE?.let { database ->
                    scope.launch(Dispatchers.IO) {
                        populateDb(
                            database.typeDao()
                        )
                    }
                }
            }
        }

        fun populateDb(typeDao: TypeDao){
            typeDao.deleteAll()
            /*out*/
            typeDao.insert(
                Type(
                    "000",
                    "Makan",
                    0
                )
            )
            typeDao.insert(
                Type(
                    "001",
                    "Transportasi",
                    0
                )
            )
            typeDao.insert(
                Type(
                    "002",
                    "Makanan Ringan",
                    0
                )
            )
            typeDao.insert(
                Type(
                    "003",
                    "Komunikasi",
                    0
                )
            )

            /*in*/
            typeDao.insert(Type(
                "500",
                "Gaji",
                1))
            typeDao.insert(
                Type(
                    "5001",
                    "Hadiah",
                    1
                )
            )
        }

    }
}

我的第二张桌子

@Database(entities = [LogKeuangan::class], version = 2)
abstract class LogKeuanganRoomDb : RoomDatabase() {
    abstract fun logKeuanganDao(): LogKeuanganDao

    companion object {
        @Volatile
        private var INSTANCE: LogKeuanganRoomDb? = null

        fun getDataBase(
            context: Context,
            scope: CoroutineScope
        ): LogKeuanganRoomDb {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    LogKeuanganRoomDb::class.java,
                    Cons.DB_NAME
                )
                    .fallbackToDestructiveMigration()
                    .build()

                INSTANCE = instance
                instance
            }
        }

    }
}

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    中明确提到的所有内容

    java.lang.IllegalStateException: Room 无法验证数据完整性。看起来您已更改架构但忘记更新版本号。您可以通过增加版本号来解决此问题。

    你只需要增加版本并将exportSchema设置为false

    来自

    @Database(entities = [Type::class], version = 3)
    

    @Database(entities = [Type::class], version = 4, exportSchema = false)
    

    注意

    @Database 如果您希望所有表属于同一个数据库,则创建另一个数据库 然后将它们包含在一个数据库中。你不应该为每个创建新的数据库 表

    【讨论】:

    • 我已经尝试过从 Android Studio 运行是正常的,但是当我关闭应用程序并从我的手机而不是 Android Studio 重新打开时,我得到了那个错误
    • @Database 如果您希望所有表属于同一个数据库,则创建另一个数据库,然后将它们包含到一个数据库中。你不应该为每个表创建新的数据库
    • 所以只使用 1 个 RoomDatabase 类?
    • 它的工作,删除第二个 RoomDatabasee 类非常感谢你
    【解决方案2】:

    如果您更改了架构,那么您需要提供迁移类来更新现有数据以匹配架构:

    https://developer.android.com/training/data-storage/room/migrating-db-versions

    //EXAMPLE TAKEN DIRECTLY FROM THE LINK SUPPLIED:
    
    val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
                    "PRIMARY KEY(`id`))")
        }
    }
    
    val MIGRATION_2_3 = object : Migration(2, 3) {
        override fun migrate(database: SupportSQLiteDatabase) {
            database.execSQL("ALTER TABLE Book ADD COLUMN pub_year INTEGER")
        }
    }
    
    Room.databaseBuilder(applicationContext, MyDb::class.java, "database-name")
            .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build()
    

    您也可以在重新安装数据库更改之前手动卸载应用程序,然后在应用程序发布之前您无需担心迁移。

    【讨论】:

      【解决方案3】:

      感谢Jasurbek

      我删除了我的第二个 RoomDatabase 类,并将我的第二个表添加到实体

      完成了

      @Database(entities = [Type::class, LogKeuangan::class], version = 3)
      abstract class TypeRoomDb : RoomDatabase(){
      
          abstract fun typeDao() : TypeDao
          abstract fun logKeuanganDao() : LogKeuanganDao
      

      【讨论】:

        猜你喜欢
        • 2017-10-27
        • 2017-11-16
        • 2021-08-07
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 1970-01-01
        • 2019-12-19
        • 2021-07-15
        相关资源
        最近更新 更多