Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data remove object from to-many set not saving

Hi I'm wondering if anyone could help me work out this Core Data issue.

I currently have two entites, User and Product. User has a to-many relationship to Product with no inverse relationship (as I don't want to know what Users have the Product, just what Products a User has. Adding a product to a user works fine using the addProductsObject method in the sub-classes Xcode generates for me. The problem is when I try to remove the Product object from the User using the removeProductsObject it seems fine. The context is closed on applicationDidEnterBackground in the AppDelegate. However if I run my application in Xcode or kill the application and start it again, the relationship is still there like it wasn't deleted!

Objective-C, iOS 8 Simulator, Xcode 6.1.1

Anyone have any idea's?

UPDATE: Zip Project here if anyone would like to take a look!

Image Link to the screenshot of relationships settings

enter image description here

Adding Product:

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
  [user addProductsObject:[self.products objectAtIndex:indexPath.row]];
  [self.navigationController popViewControllerAnimated:YES];
}

Removing Product:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [user removeProductsObject:[self.products objectAtIndex:indexPath.row]];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

SQL Logs:

2015-02-18 22:41:17.635 Project[22802:1254740] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZDOB, t0.ZEMAIL, t0.ZFIRSTNAME, t0.ZLASTNAME, t0.ZLOCATION, t0.ZPASSWORD, t0.ZUSERNAME FROM ZUSER t0 WHERE  t0.ZUSERNAME = ? 
2015-02-18 22:41:17.635 Project[22802:1254740] CoreData: annotation: sql connection fetch time: 0.0003s
2015-02-18 22:41:17.635 Project[22802:1254740] CoreData: annotation: total fetch execution time: 0.0005s for 1 rows.
2015-02-18 22:41:18.958 Project[22802:1254740] CoreData: sql: SELECT 0, t0.Z_PK FROM ZPRODUCT t0 WHERE  t0.Z6PRODUCTS = ? 
2015-02-18 22:41:18.959 Project[22802:1254740] CoreData: annotation: sql connection fetch time: 0.0002s
2015-02-18 22:41:18.959 Project[22802:1254740] CoreData: annotation: total fetch execution time: 0.0004s for 2 rows.
2015-02-18 22:41:18.959 Project[22802:1254740] CoreData: annotation: to-many relationship fault "products" for objectID 0xd000000000040000 <x-coredata://1C19A10A-BD0E-480B-B4A2-F6BBB26D9F74/User/p1> fulfilled from database.  Got 2 rows
2015-02-18 22:41:18.963 Project[22802:1254740] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBARCODE, t0.ZCALORIES, t0.ZCARBOHYDRATES, t0.ZDESC, t0.ZFAT, t0.ZFIBRE, t0.ZNAME, t0.ZPROTEIN, t0.ZSALT, t0.Z6PRODUCTS FROM ZPRODUCT t0 WHERE  t0.Z_PK = ? 
2015-02-18 22:41:18.963 Project[22802:1254740] CoreData: annotation: sql connection fetch time: 0.0002s
2015-02-18 22:41:18.963 Project[22802:1254740] CoreData: annotation: total fetch execution time: 0.0005s for 1 rows.
2015-02-18 22:41:18.964 Project[22802:1254740] CoreData: annotation: fault fulfilled from database for : 0xd0000000000c0002 <x-coredata://1C19A10A-BD0E-480B-B4A2-F6BBB26D9F74/Product/p3>
2015-02-18 22:41:18.965 Project[22802:1254740] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBARCODE, t0.ZCALORIES, t0.ZCARBOHYDRATES, t0.ZDESC, t0.ZFAT, t0.ZFIBRE, t0.ZNAME, t0.ZPROTEIN, t0.ZSALT, t0.Z6PRODUCTS FROM ZPRODUCT t0 WHERE  t0.Z_PK = ? 
2015-02-18 22:41:18.965 Project[22802:1254740] CoreData: annotation: sql connection fetch time: 0.0002s
2015-02-18 22:41:18.965 Project[22802:1254740] CoreData: annotation: total fetch execution time: 0.0003s for 1 rows.
2015-02-18 22:41:18.965 Project[22802:1254740] CoreData: annotation: fault fulfilled from database for : 0xd000000000100002 <x-coredata://1C19A10A-BD0E-480B-B4A2-F6BBB26D9F74/Product/p4>

Running [managedObjectContext save:] produces these log, quite strange why there isn't an update. Also why Product has a field called products. I opened the SQL database and in the entity Product there is an int called Products.

ANSWERED The problem is I wrote some of my own method getters for the Core Data Object and that seemed to break the core data generation classes. Got rid of these and it all works fine! I've got the inverse in too now.

like image 763
Aimson Avatar asked Mar 17 '23 23:03

Aimson


2 Answers

I guess, but I'm not sure, your model has not setup correctly.

Does it look like the following?

enter image description here

First of all, there is a products relationships (to many) where the delete rule has been set up as cascade. In addition, there is also the inverse (user) that has been set up to nullify. Graphically, they would be the following.

For User entity, the products relationship has been set up as

enter image description here

For Product entity, the user relationship has been set up as

enter image description here

About the optional flag, you need to decide based on your needs.

Even if you don't want the inverse it's strongly suggested to set up it in order to let Core Data to maintain the graph consistency.

Then, when you delete an object, you should run a save (passing also a NSError) in order to persist changes onto disk.

About the Sqlite store, mine is as follows:

ZUSER Table

enter image description here

ZPRODUCT Table

enter image description here

like image 165
Lorenzo B Avatar answered Mar 19 '23 11:03

Lorenzo B


I had the same problem and adding inverse relatioship fixed it. Nothing else needed to be done.

like image 30
saq Avatar answered Mar 19 '23 13:03

saq