java.lang.IllegalStateException:迁移未正确处理:BriefComposition

时间:2020-07-15 10:13:07

标签: android android-room

升级我的sqlite时,出现以下错误

 java.lang.IllegalStateException: Migration didn't properly handle: BriefComposition(com.zhixin.wedeep.homepage.data.model.BriefComposition).
     Expected:
    TableInfo{name='BriefComposition', columns={cover=Column{name='cover', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, duration=Column{name='duration', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, downloadURL=Column{name='downloadURL', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='null'}, tag=Column{name='tag', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isNeedVip=Column{name='isNeedVip', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, title=Column{name='title', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
     Found:
    TableInfo{name='BriefComposition', columns={cover=Column{name='cover', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, duration=Column{name='duration', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, downloadURL=Column{name='downloadURL', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='null'}, tag=Column{name='tag', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, title=Column{name='title', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
        at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)

我已经比较了这两个TableInfo,并确定两个TableInfo之间的唯一区别是新的 版本2中添加了属性isNeedVip

这是我的BriefComposition实体

@Entity
data class BriefComposition(
        val cover: String,
        val duration: String,
        @PrimaryKey val id: String,
        val tag: String?,
        val title: String,
        val downloadURL: String,
        val isNeedVip:Boolean? //add on version 2
) : Serializable {

    companion object{

        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(
                        "ALTER TABLE 'BriefComposition' ADD COLUMN 'isNeedVip' INTEGER")
            }
        }
    }

这是我的数据库课程

Database(entities = [Composition::class,CachedCompositions::class,BrowseRecord::class,Comment::class,BriefComposition::class],
        version = 2, exportSchema = true)
@TypeConverters(Converters::class)
abstract class HomePageDatabase:RoomDatabase() {


    abstract fun compositionDao(): CompositionDao
    abstract fun compositionsDao():CompositionsDao
    abstract fun commentDao():CommentDao

    companion object {

        const val DB_NAME= "homepage-db"

        // For Singleton instantiation
        @Volatile
        private var instance: HomePageDatabase? = null

        fun getInstance(context: Context): HomePageDatabase {
            return instance
                    ?: synchronized(this) {
                        instance
                                ?: buildDatabase(context).also { instance = it }
                    }
        }

        // Create and pre-populate the database. See this article for more details:
        // https://medium.com/google-developers/7-pro-tips-for-room-fbadea4bfbd1#4785
        private fun buildDatabase(context: Context): HomePageDatabase {
            return Room.databaseBuilder(context, HomePageDatabase::class.java,DB_NAME )
                    .allowMainThreadQueries()
                    .addMigrations(BriefComposition.MIGRATION_1_2,Composition.MIGRATION_1_2)
                    .build()
        }
    }
}

我不知道为什么会这样,因为我已经将所有必要的migration添加到了Database Builder中。而且,调试代码时,我发现 database.execSQL( "ALTER TABLE 'BriefComposition' ADD COLUMN 'isNeedVip' INTEGER")没有执行

2 个答案:

答案 0 :(得分:1)

您需要为迁移脚本提供isNeedVip列的默认值:

val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(
                        "ALTER TABLE 'BriefComposition' ADD COLUMN 'isNeedVip' INTEGER NOT NULL DEFAULT 1")
            }
        }

您可以参考doc以获得更多详细信息

答案 1 :(得分:1)

添加到RoomDatabase的迁移存储在amend all the properties of all the test elements中。函数addMigrations()的文档指出:

将给定的迁移添加到可用迁移列表中。如果两个 迁移具有相同的起始版本,后一个迁移 覆盖上一个。

对于版本1到2,您有两次迁移:BriefComposition.MIGRATION_1_2Composition.MIGRATION_1_2。 Composition的迁移将覆盖BriefComposition的迁移,因此不会调用BriefComposition.MIGRATION_1_2,也不会添加列isNeedVip