Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core data migration failing with "Can't find model for source store" but managedObjectModel for source is present

I have a cocoa application using core-data, which is now at the 4th version of its managed object model.

My managed object model contains abstract entities but so far I have managed to get migration working by creating appropriate mapping models and creating my persistent store using addPersistentStoreWithType:configuration:options:error and with the NSMigratePersistentStoresAutomaticallyOption set to YES.

NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
NSURL *url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"MyApp.xml"]];
NSError *error=nil;
[theCoordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:optionsDictionary error:&error]

This works fine when I migrate from model version 3 to 4, which is a migration that involves adding attributes to several entities. Now when I try to add a new model version (version 5), the call to addPersistentStoreWithType returns nil and the error remains empty. The migration from 4 to 5 involves adding a single attribute.

I am struggling to debug the problem and have checked all the following;

  1. The source database is in fact at version 4 and the persistentStoreCoordinator's managed object model is at version 5.

  2. The 4->5 mapping model as well as managed object models for versions 4 and 5 are present in the resources folder of my built application.

  3. I've tried various model upgrade paths. Strangely I find that upgrading from an early version 3 -> 5 works .. but upgrading from 4 -> 5 fails.

  4. I've tried adding a custom entity migration policy for migration of the entity whose attributes are changing ... in this case I overrode the method beginEntityMapping:manager:error: . Interestingly this method does get called when migration works (ie when I migrate from 3 to 4, or from 3 to 5 ), but it does not get called in the case that fails ( 4 to 5 ).

I'm pretty much at a loss as to where to proceed. Any ideas to help debug this problem would be much appreciated.

like image 723
Ira Cooke Avatar asked Dec 25 '10 23:12

Ira Cooke


1 Answers

I'm answering my own question here in case it helps somebody.

The crucial problem is that, when I reached version 4 of my object model, I also added an additional managed object model to the project. This additional model was separate from my main model, and is just used to create a cache on another thread and contains data that is unrelated to the main model.

Foolishly I still initialized my managedObjectModel using

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]

which in my case created a model containing entities from my main model as well as my other model. These unwanted entities had their version hashes in my database. When core-data then goes to look for a managedobjectmodel that matches all these hashes it naturally fails to find it.

In my case the solution was to manually clean my db files prior to migration (removing versionhashes from unwanted entities) .. and then to change my managedObjectModel loading code to;

NSString *path = [[NSBundle mainBundle] pathForResource:@"MyDataModel" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
like image 56
Ira Cooke Avatar answered Sep 28 '22 20:09

Ira Cooke