private static final Migration MIGRATION_4_5 = new Migration(4, 5) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("CREATE UNIQUE INDEX idx_Member_idCardNum_unique ON Member (idCardNum);");
    }
};
  • Android 项目中,在一次 Room 数据库更新后,查询 Member 表,报如下错误
java.lang.IllegalStateException: Migration didn't properly handle: Member(com.my.acdapp.model.dbentity.Member).
Expected:
TableInfo{
	name='Member', 
	columns={
		other=Column{name='other', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		createTime=Column{name='createTime', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		idCardNum=Column{name='idCardNum', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		memberName=Column{name='memberName', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, 
		updateTime=Column{name='updateTime', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, 
		memberType=Column{name='memberType', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		memberId=Column{name='memberId', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}
	}, 
	foreignKeys=[], 
	indices=[
		Index{name='idx_member_memberId_unique', unique=true, columns=[memberId]}
	]
}
Found:
TableInfo{
	name='Member', 
	columns={
		other=Column{name='other', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		createTime=Column{name='createTime', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		idCardNum=Column{name='idCardNum', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		memberName=Column{name='memberName', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, 
		updateTime=Column{name='updateTime', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, 
		memberType=Column{name='memberType', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, 
		memberId=Column{name='memberId', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}
	}, 
	foreignKeys=[], 
	indices=[
		Index{name='idx_Member_idCardNum_unique', unique=true, columns=[idCardNum]}, 
		Index{name='idx_member_memberId_unique', unique=true, columns=[memberId]}
	]
}
问题原因
  • Room 比较了 Expected(预期的表结构)和 Found(实际存在的表结构),发现两者在 Indices (索引)部分存在差异
  1. Expected(预期的表结构)包含 1 个索引
idx_member_memberId_unique(唯一索引,基于 memberId 列)
  1. Found(实际存在的表结构)包含 2 个索引
idx_member_memberId_unique(唯一索引,基于 memberId 列)

idx_Member_idCardNum_unique(唯一索引,基于 idCardNum 列)
处理策略
  • 确保 Member 实体类的定义与预期的表结构一致,检查 @Entity 注解中的 indices 属性
// 原来是这样

@Entity(tableName = "Member",
        indices = {
                @Index(name = "idx_member_memberId_unique", value = {"memberId"}, unique = true)
        })
public class Member {
	...
}
// 修改成这样

@Entity(tableName = "Member",
        indices = {
                @Index(name = "idx_member_memberId_unique", value = {"memberId"}, unique = true),
                @Index(name = "idx_Member_idCardNum_unique", value = {"idCardNum"}, unique = true)
        })
public class Member {
	...
}

更多推荐