由于“primaryKeyPosition”值错误,房间数据库迁移测试出错

Edu*_*rdo 7 database-migration android-room

我正在测试房间迁移,在“迁移和验证”步骤中,我收到了java.lang.IllegalStateException:迁移失败。由于primaryKeyPosition“service_id”列上的值错误。深入挖掘一点,我注意到在预期方面,actual_visit_id_service_id_primary_key 中的属性具有不同的pk索引 (1, 2),而在Found方面,两者都具有相同的 (1, 1)

我检查了安装的应用程序中表actual_visit_service的数据库模式和列service_idpk2(如预期)

失败的实体:

@Entity(
    tableName = ACTUAL_VISIT_SERVICE_TABLE,
    indices = [Index(
        value = [ACTUAL_VISIT_SERVICE_SERVICE_ID, ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID], unique = true
    )],
    foreignKeys = [(ForeignKey(
        entity = ActualVisitEntity::class,
        parentColumns = [ID],
        childColumns = [ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID],
        onDelete = ForeignKey.CASCADE
    ))],
    primaryKeys = [ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID, ACTUAL_VISIT_SERVICE_SERVICE_ID]
)
data class ActualVisitServicesEntity(
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID)
    val actualVisitId: String,
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_AMOUNT)
    val amount: Double?,
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_DURATION)
    val duration: Int?,
    @ColumnInfo(name = IS_SYNCHRONIZED)
    var isSynchronized: Boolean = false,
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_HAS_BEEN_PROVIDED)
    var hasBeenProvided: Boolean,
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_REJECTION_CATEGORY)
    var rejectionCategory: String?,
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_REJECTION_REASON)
    var rejectionReason: String?,
    @ColumnInfo(name = ACTUAL_VISIT_SERVICE_SERVICE_ID)
    val serviceId: String
) : BaseEntity() {
....
}
Run Code Online (Sandbox Code Playgroud)

迁移:

        @JvmField
        val MIGRATION_18_TO_19 = object : Migration(18, 19) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE planned_visit ADD COLUMN hint TEXT")
            }
        }
Run Code Online (Sandbox Code Playgroud)

我得到的错误:

java.lang.IllegalStateException: Migration failed.
Expected:TableInfo{name='actual_visit_services', columns={duration=Column{name='duration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}, amount=Column{name='amount', type='REAL', affinity='4', notNull=false, primaryKeyPosition=0}, actual_visit_id=Column{name='actual_visit_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, rejection_category=Column{name='rejection_category', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, has_been_provided=Column{name='has_been_provided', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, service_id=Column{name='service_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=2}, rejection_reason=Column{name='rejection_reason', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, is_synchronized=Column{name='is_synchronized', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[ForeignKey{referenceTable='actual_visits', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[actual_visit_id], referenceColumnNames=[id]}], indices=[Index{name='index_actual_visit_services_service_id_actual_visit_id', unique=true, columns=[service_id, actual_visit_id]}]} 
found:TableInfo{name='actual_visit_services', columns={duration=Column{name='duration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}, amount=Column{name='amount', type='REAL', affinity='4', notNull=false, primaryKeyPosition=0}, actual_visit_id=Column{name='actual_visit_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, rejection_category=Column{name='rejection_category', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, has_been_provided=Column{name='has_been_provided', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, service_id=Column{name='service_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, rejection_reason=Column{name='rejection_reason', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, is_synchronized=Column{name='is_synchronized', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[ForeignKey{referenceTable='actual_visits', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[actual_visit_id], referenceColumnNames=[id]}], indices=null}
Run Code Online (Sandbox Code Playgroud)

正如您在“预期”中看到的那样,您有:

service_id=Column{name= ... primaryKeyPosition=2}
Run Code Online (Sandbox Code Playgroud)

但在“找到”上:

service_id=Column{name= ... primaryKeyPosition=1}
Run Code Online (Sandbox Code Playgroud)

我从一开始就使用 Room,但我只是从迁移开始,是以前的数据库构建版本 18 和新的 19。我运行常规实体和 DAO 测试,Robolectric我打算对迁移测试做同样的事情。

为什么组合主键中的两个属性在迁移的数据库中有相同的pk索引?