In my CoreData model I created an abstract entity (IDManagedObject
) to share a common attribute for my other entities.
When I first ran it I got several Cannot merge multiple root entity source tables into one destination entity root table
errors.
The complete error is as follows:
Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, reason=Cannot migrate store in-place: Cannot merge multiple root entity source tables into one destination entity root table, destinationURL=file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, NSUnderlyingError=0x6000019fb810 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={message=Cannot merge multiple root entity source tables into one destination entity root table, destinationRootEntity=IDManagedObject, NSUnderlyingException=Cannot merge multiple root entity source tables into one destination entity root table, sourceRootEntities=(
Book,
Author
), reason=Cannot merge multiple root entity source tables into one destination entity root table}}}, ["NSUnderlyingError": Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={message=Cannot merge multiple root entity source tables into one destination entity root table, destinationRootEntity=IDManagedObject, NSUnderlyingException=Cannot merge multiple root entity source tables into one destination entity root table, sourceRootEntities=(
Book,
Author
), reason=Cannot merge multiple root entity source tables into one destination entity root table}, "destinationURL": file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, "sourceURL": file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, "reason": Cannot migrate store in-place: Cannot merge multiple root entity source tables into one destination entity root table]: file MyApp/SceneDelegate.swift, line 96
Interestingly, it only shows the error for those two entities, but I have many more.
After doing a bit of searching I found I need to add a mapping model to migrate between the old and new version. So I added that via Cmd-N in Xcode and selecting the source and destination model.
But I am still getting the error.
Both shouldMigrateStoreAutomatically
and shouldInferMappingModelAutomatically
are set to true
.
What am I missing here?
The old model is in the current app written in Objective-C, the new model is in a new version of the app written is Swift and now also uses CloudKit
. Using Xcode 12.2.
I am happy to add more info if needed, just don't know what would be relevant for the question.
The short version is that automatic lightweight migration can't make this change, even with a mapping model. You need to do a full manual migration to make this change. If you check out Apple's lightweight migration documentation, it says that
...if two existing entities do not share a common parent in the source, they cannot share a common parent in the destination.
This is what you're trying to do, but it can't happen automatically.
The longer answer to why gets into some details of how Core Data works. Xcode doesn't do a good job of making this obvious.
Book
table, an Author
table, and so on.IDManagedObject
table. Core Data uses other logic to decide if an entry in that table is a Book
or an Author
or something else.Because of this, what you're actually doing is merging more than one entity into a single new entity. Core Data doesn't know how to do that automatically, which is what it's telling you in that error message.
Core Data is only complaining about those two tables because they're the first ones it sees. It can't handle merging any of them, and it only mentions two tables because it's giving up before looking at the rest.
To make this change, you'll need to create a migration manager and write code to do the migration. Apple describes this in Customizing the Migration Process. Or, depending on what exactly you need, there might be other solutions that don't require adding a new parent entity.