Область db DynamicRealmObject недопустима во время миграции - PullRequest
0 голосов
/ 06 мая 2019

Я работаю с Realm уже более года, поэтому я не новичок во всем процессе миграции, но это заставляет меня почесать голову в течение нескольких дней:

Во время миграции данных на новыйверсия схемы Мне нужно создать некоторые объекты и вставить их в БД, а затем подключить их к объектам другого типа.

Сначала я создаю карту динамических объектов, чтобы позже я мог подключить их ко второму типу.:

    val generatedStoreVisitTypes = mutableMapOf<String, DynamicRealmObject>()

Затем я создаю и использую dynamicObjects:

fun migrateToVersion19(realm: DynamicRealm) {

    // an extension method I created which adds the field if it doesn’t exist already, impl at the bottom
    realm.schema.getOrCreate<RealmMetadata>()
        // an extension method I created which adds the field if it doesn’t exist already, impl at the bottom
        .safeAddRealmListField(RealmMetadata::storeVisitTypes, realm.schema)
        .transform { metadata ->
            // I use the string name of the property here and not reflection since this field is deleted during this migration
            val currentStoreTaskList = metadata.getList("storeTasks")
            currentStoreTaskList.forEach { storeTasks ->
                // create an instance here and initialise it
                val visitTypeTasks = realm.createObject(MetaVisitTypeTasks::class.java.simpleName)
                visitTypeTasks[MetaVisitTypeTasks::visitTypeId.name] = "1"
                val visitTasks = visitTypeTasks.getList(MetaVisitTypeTasks::visitTasks.name)
                storeTasks.getList("storeTasks").forEach {
                    visitTasks.add(it)
                }

                // save the object to the map
                generatedStoreVisitTypes[storeUid] = visitTypeTasks
                }
            }
            .safeRemoveField("storeTasks")

        realm.schema.getOrCreate<RealmStore>()
        .safeAddRealmListField(RealmStore::visitTypes, realm.schema)
        .transform {
            val storeUid = it.getString(RealmStore::storeUid.name)
            // crash here on the “add” method
            it.getList(RealmStore::visitTypes.name).add(generatedStoreVisitTypes[storeUid])
        }
    }
}

private inline fun <reified T> RealmSchema.getOrCreate(): RealmObjectSchema {
    return get(T::class.java.simpleName) ?: create(T::class.java.simpleName)
}

private inline fun <reified TClass : RealmObject, reified TListItem : RealmObject, reified TList : RealmList<TListItem>> RealmObjectSchema.safeAddRealmListField(addedField: KMutableProperty1<TClass, TList>, schema: RealmSchema): RealmObjectSchema {
    val fieldName = addedField.name
    val listItemObjectSchema = schema.get(TListItem::class.java.simpleName)

    if (!hasField(fieldName)) {
        return addRealmListField(fieldName, listItemObjectSchema)
    }
    return this
}


Вызов метода «add» во втором методе «transform» иногда вызывает -

«Java.lang.IllegalStateException: объект больше не действителен для работы.Была ли она удалена другим потоком? »

Я знаком с этой ошибкой и обычно знаю, как с ней справиться, но не могу воссоздать ее или понять, как такое происходит в этом случае.Поскольку мы говорим о миграции, не должно быть другого потока, работающего по той же схеме - поскольку выполнение синхронизировано, не так ли?Кроме того, мы говорим об объекте, который был только что создан .Нет другого контекста, в котором на него ссылаются или используют.

Я не понимаю, как этот объект может быть удален.Что может вызвать такую ​​ошибку?

...