Core Data question: Illegal attempt to establish a relationship 'project' between objects in different contexts

1,329 views
Skip to first unread message

Dr Nic Williams

unread,
Jan 4, 2009, 7:10:04 PM1/4/09
to cocoah...@googlegroups.com

My model of entities is simple: Project -> ProjectCommit, with a class Project, ProjectCommit for each entity.

I fetch the Project instances from a NSManagedObjectContext + NSFetchRequest, and then for each Project I use the asynchronous NSURLConnection -connectionWithRequest:delegate: to fetch a remote page, and a delegate on the Project class to parse it and then create some ProjectCommit instances.

When I create the ProjectCommits I want to associate them to their parent Project, but I get the following error:

2009-01-05 09:58:52.091 GitHub Chat[53339:10b] Illegal attempt to establish a relationship 'project' between objects in different contexts (source = <ProjectCommit: 0x800519a20> (entity: ProjectCommit; id: 0x8004bee80 <x-coredata:///ProjectCommit/t494E4AE7-C31C-4FEB-9B37-5DE6AAC9EEB85> ; data: {

    comments =     (

    );

    "commit_sha" = nil;

    "commit_url" = nil;

    desc = nil;

    project = 0x8002bb820 <x-coredata://5298BFF3-D26C-4BF5-834B-BEF8F1205194/Project/p102>;

}) , destination = <Project: 0x8002eb820> (entity: Project; id: 0x8002bb820 <x-coredata://5298BFF3-D26C-4BF5-834B-BEF8F1205194/Project/p102> ; data: {

    commits =     (

        0x8004bee80 <x-coredata:///ProjectCommit/t494E4AE7-C31C-4FEB-9B37-5DE6AAC9EEB85>

    );

    name = "rails/rails";

    projectname = rails;

    username = rails;

}))



I am creating the ProjectCommit objects in a new NSManagedObjectContext, and the error above occurs when saving the context.

Should I be using the same NSManagedObjectContext to create the ProjectCommit objects that I used to fetch the parent Project objects? Or why is there an issue?

I've even tried to re-fetch the Project object through the new NSManagedObjectContext with:

   selfWithinContext = [moc objectWithID:[self objectID]]

But get the same error.

Anyone seen this issue before?

Cheers
nic

--
Dr Nic Williams
Mocra - Premier iPhone and Ruby on Rails Consultants
w - http://mocra.com
e - dr...@mocra.com
p - +61 412 002 126 or +61 7 3102 3237
skype - nicwilliams

Matt Gallagher

unread,
Jan 4, 2009, 7:17:24 PM1/4/09
to cocoah...@googlegroups.com
Everything you fetch/create/connect using Core Data must be in the
same NSManagedObjectContext. There's no abiguity -- everything that is
connected *must* be in the same context.

In this case, you must create the ProjectCommit objects using the same
NSManagedObjectContext from which you fetched the Projects, otherwise
you can never connect the two.

Cheers,

Matt.

Dr Nic Williams

unread,
Jan 4, 2009, 7:22:01 PM1/4/09
to cocoah...@googlegroups.com
So I can add + save, add + save, remove + save, using the same context?

When do I need another NSManagedObjectContext then?

Cheers
Nic

Matt Gallagher

unread,
Jan 4, 2009, 7:37:40 PM1/4/09
to cocoah...@googlegroups.com
On 05/01/2009, at 11:22 AM, Dr Nic Williams wrote:

> So I can add + save, add + save, remove + save, using the same
> context?

Yes.

On 05/01/2009, at 11:22 AM, Dr Nic Williams wrote:

> When do I need another NSManagedObjectContext then?

If you're only accessing one SQLite file on disk? Almost never.

You need a separate context if you're working with a separate SQLite
files on disk. But if you have two files open at once, copying data
from one to the other must be done manually.

For example: multiple documents. If you want to copy and paste between
two NSPersistentDocuments (which are each backed by their own
NSManagedObjectContexts) you must serialize the copied objects from
the first NSManagedObjectContext yourself (using NSKeyedArchiver will
work but you must implement protocol methods) and then reconstruct
them yourself in the second NSManagedObjectContext.

There are less common situations where you may open the same SQLite
file in multiple contexts. Normally due to multi-threading. You should
never use the same context in multiple threads -- even if all threads
are just reading. To read from the same Core Data archive in multiple
threads, open a new NSManagedObjectContext in each thread -- and
perform all work independently.

Cheers,

Matt.

Dr Nic Williams

unread,
Jan 4, 2009, 7:48:27 PM1/4/09
to cocoah...@googlegroups.com
Using NSURLConnection asynchronously doesn't use threads does it? The delegate is invoked in the original thread?

Matt Gallagher

unread,
Jan 4, 2009, 7:55:47 PM1/4/09
to cocoah...@googlegroups.com
Correct.

The NSURLConnection delegate is invoked from the run loop with which it is scheduled (run loops are thread-specific). If you let the NSURLConnection schedule itself automatically, it will schedule with the current thread. If you choose, you can use the startImmediately:NO construction for NSURLConnection and then schedule on any NSRunLoop you want.

Cheers,

Matt.
Reply all
Reply to author
Forward
0 new messages