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

1

12

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.

Jeramie answered 25/12, 2010 at 23:22 Comment(0)
J
16

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];
Jeramie answered 26/12, 2010 at 12:51 Comment(2)
Ira, I'm having this problem as well. When you say you manually cleaned your db files, do you mean that you removed version hashes in code? I shipped my previous database version with the merged model, so I can't edit the bundle directly.Innkeeper
Sorry for the glacially slow response. Yes I did clean the version hashes in code. I must admit I haven't actually looked at this for a long time now but I think I needed to do it because the version hashes for all objects in the merged model get saved in the users database. Hence old databases need cleaning in code prior to migration.Jeramie

© 2022 - 2024 — McMap. All rights reserved.