The Batting.team relationship doesn't always save properly and returns null sometimes
About 100 'Team' NSManagedObjects are saved and can log their attributes as expected. Then about 15000 'Batting' NSManagedObjects are saved and all attributes log correctly except for the relationship.
I want the Batting.team relationship to point to the Team object which has the same Team.teamID value as the Batting.teamID.
When setting the Batting relationship, I create a predicate to search for a specific Team.teamID, fetch the request and supposedly set that Team object to equal my Batting.team relationship. Sometimes the relationship attribute gets set but most times it doesn't and I can't figure this out
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSError *error;
NSString* dataPath_TEAMS = [[NSBundle mainBundle] pathForResource:@"teams" ofType:@"json"];
NSArray* TEAMS = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath_TEAMS] options:kNilOptions error:&error];
NSString* dataPath_ABC = [[NSBundle mainBundle] pathForResource:@"abc" ofType:@"json"];
NSArray* BATTING_ABC = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath_ABC] options:kNilOptions error:&error];
//insert Team objects
NSFetchRequest *fetchRequestTeams = [[NSFetchRequest alloc] init];
NSEntityDescription *entityTeams = [NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
[fetchRequestTeams setEntity:entityTeams];
for (id t in TEAMS) {
Team *team = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
team.name = [t objectForKey:@"name"];
team.minYearID = [t objectForKey:@"minYearID"];
team.maxYearID = [t objectForKey:@"maxYearID"];
team.teamID = [t objectForKey:@"teamID"];
if (![self.managedObjectContext save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}
NSArray *fetchedObjectsTeams = [self.managedObjectContext executeFetchRequest:fetchRequestTeams error:&error];
NSLog(@"Number of records in teams.json - %d", (int)[fetchedObjectsTeams count]);
//insert Batting objects
NSFetchRequest *fetchRequestBatting = [[NSFetchRequest alloc] init];
NSEntityDescription *entityBatting = [NSEntityDescription entityForName:@"Batting" inManagedObjectContext:self.managedObjectContext];
[fetchRequestBatting setEntity:entityBatting];
for (id b in BATTING_ABC) {
Batting *batting = [NSEntityDescription insertNewObjectForEntityForName:@"Batting" inManagedObjectContext:self.managedObjectContext];
batting.playerID = [b objectForKey:@"playerID"];
batting.h = [b objectForKey:@"h"];
batting.ab = [b objectForKey:@"ab"];
batting.hr = [b objectForKey:@"hr"];
batting.rbi = [b objectForKey:@"rbi"];
batting.sb = [b objectForKey:@"sb"];
batting.r = [b objectForKey:@"r"];
batting.bb = [b objectForKey:@"bb"];
batting.so = [b objectForKey:@"so"];
batting.yearID = [b objectForKey:@"yearID"];
batting.teamID = [b objectForKey:@"teamID"];
NSPredicate *teamIDPredicate = [NSPredicate predicateWithFormat:@"teamID == %@", [b objectForKey:@"teamID"]];
[fetchRequestTeams setPredicate:teamIDPredicate];
NSArray *fetchedSpecificTeam = [self.managedObjectContext executeFetchRequest:fetchRequestTeams error:&error];
batting.team = [fetchedSpecificTeam firstObject];
if (![self.managedObjectContext save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}
fetchedObjectsBatting = [self.managedObjectContext executeFetchRequest:fetchRequestBatting error:&error];
for (Batting *b in fetchedObjectsBatting) {
NSLog(@"playerID: %@", b.playerID);
NSLog(@"yearID: %@", b.yearID);
NSLog(@"teamID: %@", b.teamID);
NSLog(@"team: %@\n\n", b.team.name);
}
return YES;
}
From the screenshot of your model, it is configured so that each
Team
can have only oneBatting
. Each time you setbatting.team
to a givenTeam
, CoreData will remove the link from thatTeam
to its current Batting object (thereby setting thatBatting
object'steam
to nil).You should define the
Team
entity'sbatting
relationship to be "to-Many" (eachTeam
can have manyBattings
) using the Data Model inspector on the right hand side when in the model editor: