Я работаю с 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: объект больше не действителен для работы.Была ли она удалена другим потоком? »
Я знаком с этой ошибкой и обычно знаю, как с ней справиться, но не могу воссоздать ее или понять, как такое происходит в этом случае.Поскольку мы говорим о миграции, не должно быть другого потока, работающего по той же схеме - поскольку выполнение синхронизировано, не так ли?Кроме того, мы говорим об объекте, который был только что создан .Нет другого контекста, в котором на него ссылаются или используют.
Я не понимаю, как этот объект может быть удален.Что может вызвать такую ошибку?