bitdoctor
bitdoctor

Reputation: 11

New "Illegal attempt to establish a relationship 'xyz' between objects in different contexts"

when trying to add Core Data Objects in a second NSManagedObjectContext, I get an error saying Illegal attempt to establish a relationship 'info' between objects in different contexts. However, the two entities are on the same context (at least, they should). The debuger gives the identical hex-number. What is wrong with this code?

-(void) loadHistoricalPrices
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Create context on background thread
if(document!=NULL)
{
    NSManagedObjectContext *context = NULL;
    NSNotificationCenter *nc =NULL;

    context = [[NSManagedObjectContext alloc] init];
    [context setUndoManager:nil];
    [context setPersistentStoreCoordinator: [document.managedObjectContext persistentStoreCoordinator]];


    // Register context with the notification center
    nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self
           selector:@selector(mergeChanges:)
               name:NSManagedObjectContextDidSaveNotification
             object:context];

    NSEntityDescription * infoEntity;
    infoEntity = [NSEntityDescription entityForName:@"Info" inManagedObjectContext:context];
    NSEntityDescription * historyEntity;
    historyEntity = [NSEntityDescription entityForName:@"History" inManagedObjectContext:context];



// fetching an object-array of info-entity, called result

    if([result count]>0)
    {

        NSArray * items;
       // getting items to insert into history-entity


        for(NSString * item in items)
        {
            NSArray * subs;
            subs=[item componentsSeparatedByString:@","];
            if([subs count]>5)
            {
                    HistoryMO * newHistory;

                    newHistory = [[[HistoryMO alloc] initWithEntity:historyEntity insertIntoManagedObjectContext:context] autorelease];
                    [newHistory setValue:[NSNumber numberWithDouble:[[subs objectAtIndex:4] doubleValue]] forKey:@"course"];
[newHistory setValue:infoMO forKey:@"info"];

// >>>>> CRASHES HERE

            }                
        }
    }


    // merge data
    if([[[context persistentStoreCoordinator] persistentStores] count]>0)
    {
        NSLog(@"saving...");

        error=NULL;
        [context save:&error];
        if (!error) [context reset]; else NSLog(@"error saving historic prices %@",[error localizedDescription]);
        if (!error) NSLog(@"saved successfully");
    }

    [nc removeObserver:self];
    [context release];
}
[pool release];
}

Upvotes: 1

Views: 737

Answers (3)

user1203625
user1203625

Reputation: 23

If infoMO is from the same context it gets invalidated after you call [context reset] in the following line:

if (!error) [context reset]; else NSLog(@"error saving historic prices %@",[error localizedDescription]);

So you need to refetch it. That is why ChrisH's solution worked.

Upvotes: 1

ChrisH
ChrisH

Reputation: 4558

Hard to tell from your code sample, but based on your crash information, your infoMO object is from another context. You cannot create a relationship between two objects from different contexts.

The simplest solution is to get a reference to the infoMO in the current context by using NSManagedObject's objectID property.

Assuming that your infoMO instance is of the Info class, you'd do this:

Info *contextInfoMO = [context objectWithID:infoMO.objectID];
[newHistory setValue:contextInfoMO forKey:@"info"];

Upvotes: 0

mprivat
mprivat

Reputation: 21902

Where's infoMO coming from? It looks like it's happening where you have the // getting items to insert into history-entity comment. My guess is you are using a different context to fetch these objects. You have to use the same context to lookup your infoMO objects as the one you are using to insert into the HistoryMO, or else the context can't manage the relationship.

Upvotes: 0

Related Questions