Core Data, to-many relationships, and object graph consistency
Core Data, to-many relationships, and object graph consistency
- Subject: Core Data, to-many relationships, and object graph consistency
- From: Sebastian Celis <email@hidden>
- Date: Sun, 14 Jun 2009 14:20:19 -0500
Hello,
I am having difficulty understanding how to work with a fairly simple
Core Data model involving to-many relationships and their inverses.
Imagine the following entities, attributes, and relationships:
* Book
- title (NSString* attribute)
- author (NSString* attribute)
- tags
+ to-many relationship to the BookTag entity
+ inverse is the 'book' relationship
+ delete rule is 'Cascade'
* BookTag
- book
+ to-one relationship to the Book entity
+ inverse is the 'tags' relationship
+ delete rule is 'Nullify'
- tag
+ to-one relationship to the Tag entity
+ inverse is the 'bookTags' relationship
+ delete rule is 'Nullify'
* Tag
- name (NSString* attribute)
- bookTags
+ to-many relationship to the BookTag entity
+ inverse is the 'tag' relationship
+ delete rule is 'Cascade'
It is a simple tagging model. I want to be able to create tags and
assign them to books. It makes sense to break BookTag and Tag into two
separate entities so that I can easily query for all books that
contain a certain tag, as well as all of the tags defined in the
system.
First question: do the details of this model make sense for the data?
Some of the inverse relationships (like Tag.bookTags and BookTag.book)
seem unnecessary, but from what I have read, 99% of the time you
really want to model an inverse for every relationship. And are the
delete rules correct? They all make sense to me but I wanted
confirmation on the delete rules for the BookTag relationships. Does
nullify make sense for both of them?
Now that I have described the model, I would like to get to the heart
of this e-mail. I am having difficulty understanding how consistency
in the object graph is maintained for these entities and
relationships. For example, the following code seems strange to me:
SCBook *book = [NSEntityDescription insertNewObjectForEntityForName:@"Book"
inManagedObjectContext:managedObjectContext];
[book setTitle:@"1984"];
[book setAuthor:@"George Orwell"];
SCTag *tag1 = [NSEntityDescription insertNewObjectForEntityForName:@"Tag"
inManagedObjectContext:managedObjectContext];
[tag1 setName:@"scifi"];
SCBookTag *bookTag1 = [NSEntityDescription
insertNewObjectForEntityForName:@"BookTag"
inManagedObjectContext:managedObjectContext];
[bookTag1 setTag:tag1];
[bookTag1 setBook:book];
SCTag *tag2 = [NSEntityDescription insertNewObjectForEntityForName:@"Tag"
inManagedObjectContext:managedObjectContext];
[tag2 setName:@"dystopian"];
SCBookTag *bookTag2 = [NSEntityDescription
insertNewObjectForEntityForName:@"BookTag"
inManagedObjectContext:managedObjectContext];
[bookTag2 setTag:tag2];
[bookTag2 setBook:book];
>From what I understand, Core Data should automatically maintain
consistency in my object graphs, correct? So then why does [[book
tags] count] equal 1 at this point? Shouldn't both of these BookTag
entities exist in the [book tags] set? Even if I re-fetch this
particular book entity, the count of the tags set is still 1. However,
saving this data and then relaunching the app or calling
[managedObjectContext reset] appears to rectify this, allowing me to
see both SCBookTag objects in the [book tags] set.
On the other hand, if I remove the [bookTag1 setBook:book] and
[bookTag2 setBook:book] lines and instead write:
NSMutableSet *theTags = [book mutableSetValueForKey:@"tags"];
[theTags addObject:bookTag1];
[theTags addObject:bookTag2];
Now, [[book tags] count] equals two! What about this situation am I
not understanding correctly? What is the correct way to do this? It
seems as though forcing me to use mutableSetValueForKey is strange,
especially because I would then have to do this for the Tag.bookTags
relationship as well instead of simply calling [bookTag1 setTag:tag1].
In general, these particular entities and relationships are giving me
a lot of grief. For example, I have test code that can add new Tag and
BookTag objects to an existing book and save them to the persistent
store. I also have test code that can successfully delete existing Tag
and BookTag objects. However, when I run both pieces of test code at
the same time (add a new BookTag and delete an existing BookTag) and
try to save , I get an error stating that there is a dangling
reference to an invalid object (a BookTag object). I have a feeling
that my misunderstandings above and the manner in which I am creating
my objects is causing inconsistencies in my object graph which are
then manifesting in this particular situation.
Does anyone have any advice that would clarify things and put me on
the right track?
Thank you,
Sebastian
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden