How to refactor a core data model to make two existing entities inherit from a new abstract entity

I've solved the problem. I'm going be detailed here so other people can use this as a resource. I'm not completely sure about the inner workings of core data, but it seemed to choke when trying to create a new abstract entity and have two existing entities merge into it. So the solution I came up with was to ditch the old entities and create 3 brand new ones and create a mappingmodel to map data from the old entities onto the new ones.

Given the following entities that need to inherit from a new abstract entity.

  • Snake
  • Mouse

Step 1 - create new model version

Create a new model version and create 3 new entities. Delete the old ones. I used different names for the new entities. I'm not sure if there's a way to accomplish this by keeping the names the same.

  • Serpent (replaces snake)
  • Rodent (replaces mouse)
  • Animal (new abstract entity that the other two will use as a parent)

Note: it's possible to copy and paste properties and relationships in the model designer view. You can copy them between entities and even across model versions. Just select properties from the property list in the designer view and ⌘-C. This is a big time saver when moving properties from the old entities onto the new abstract one.

Step 2 - Create a Mapping Model

Use Xcode to create a mapping model. In the creation dialog select the previous model version as the source and the new model version as the destination. The mapping model holds a list of entity mappings. Xcode should have automatically created one for each of the entities in your old model version. They follow the naming pattern of OldEntityToNewEntity. None of the new entities will have been created yet so you have to add them:

  • SnakeToSerpent

  • MouseToRodent

    (do not make one for the abstract Animal entity).

In the property inspector for each of the new mappings select the old entity as the source and the new one as the destination.

Step 3 - map the properties

Some of the properties and relationships in each entity mapping should already be present. Any property that has the same name in both the old entity and the new one should have been automatically detected and setup correctly. You'll have to add a property mapping for any property that got moved to the abstract entity. (same with relationships and fetched properties) Just reference your old model version to make sure you included all the properties you plan to continue using.

That should be it.


Just to make sure people are doing this properly, I followed the instructions given by Christian Schlensker including "do not make one for the abstract Animal entity" and (to continue his example), while it built and ran without the original "Cannot merge" error, my Serpent and Rodent were not recognised as subclasses of Animal on introspection.

In order to migrate properly I did have to create SnakeToAnimal and MouseToAnimal mappings which mapped the appropriate properties from subclass to superclass.

This may be what Christian was getting at with Step 3, but it wasn't entirely clear to me given his comment "do not make one for the abstract Animal entity" previously, as this is exactly what I had to do.