During migration one object is being duplicated for an unknown reason, and its relationships are not set causing migration to fail since the relationship is required. I have no idea why this object is being duplicated though. I would expect the same number of objects for all entities to exist after the migration as they did before.
I have an entity TVShow
, that I renamed a relationship from cast
to characters
, and added a new attribute genre
. I have a custom migration policy that sets the genre
attribute.
I created a mapping model, set the custom policy for TVShowToTVShow
and left everything else alone. A single TVSeason
object is duplicated though after the migration, and doesn't have its show
relationship set on the duplicate only. I have no idea why it was duplicated though. The TVShow
wasn't. I have a possible fix for now by fetching the new object and deleting it, but I don't want to have to include this in every migration going forward if I can't tell the cause of it in the first place.
My custom TVShow
policy is:
class TVShowToTVShowMigrationPolicy_172_to_192: NSEntityMigrationPolicy {
override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
guard dInstance.value(forKey: "genre") == nil else {
print("genre already set")
return
}
// set `genre` to the first item in `genres`
if let genres = dInstance.value(forKey: "genres") as? Set<NSManagedObject> {
dInstance.setValue(genres.first, forKey: "genre")
} else {
print("No genres found")
}
}
}
and the new policy I created to remove the duplicate is
class TVSeasonToTVSeasonMigrationPolicy_172_to_192: NSEntityMigrationPolicy {
override func endRelationshipCreation(forMapping mapping: NSEntityMapping, manager: NSMigrationManager) throws {
try super.endRelationshipCreation(forMapping: mapping, manager: manager)
print(#function)
let dContext = manager.destinationContext
let request: NSFetchRequest<NSManagedObject> = NSFetchRequest<NSManagedObject>(entityName: "TVSeason")
request.predicate = NSPredicate(format: "%K == nil", #keyPath(TVSeason.show))
let seasons = try dContext.fetch(request)
print(seasons)
for season in seasons {
dContext.delete(season)
}
}
}
Is this potentially a CoreData issue and I should just go with the de-duplicate policy, or is there anything I can do to prevent the duplicate from existing in the first place?
I am not using CloudKit which I've read has a similar issue.