More CoreData questions...

  • I am doing something very similar to what Martin is doing...

    I have a legacy Access DB that I am loading via an ODBC connection
    into Obj-C arrays.  I am then cycling thru each table picking out only
    specific fields of the table to put under CoreData's control in a
    SQLLite store.  I am cycling thru doing fetches based on integer ID's
    to recreate the relationships that I need.

    I already have my indexes indexed and have some pretty simple fetch
    requests defined that make the code easy to write and implement.

    When I get to the first table that I need to recreate a one-to many
    relationship I find that if after specifying the first connection if I
    don't force a save of the managedObjectContext then the next fetch
    that is for the index comes up with 0 results.  Here is part of my
    code...

    SessionTable *st = [clientCountsDB st];
    numRows = [st getNumberOfRows];

    for ( i=0; i < numRows; i++ )
    {
    sold = [clientCountsDB getSession:i];

    Classes *c = [[Classes alloc] initWithEntity:classesEntity
    insertIntoManagedObjectContext:moc];
    c.Class_ID = [NSNumber numberWithUnsignedLong:[[sold Session_ID]
    integerValue]];
    c.Date_Held = [NSDate dateWithString:[[sold Class_Datetime]
    stringByAppendingString:@" -0500"]];

    NSDictionary *substitutionDictionary = [NSDictionary
    dictionaryWithObjectsAndKeys:
          [sold Teacher_ID], @"FETCH_ID", nil];
    NSFetchRequest *fetchRequest = [[coreDataDelegate managedObjectModel]
        fetchRequestFromTemplateWithName:@"GetPersonByID"
        substitutionVariables:substitutionDictionary];
    NSArray *results = [moc executeFetchRequest:fetchRequest error:&error];

    if ( results != nil ) {
      if ( [results count] == 0 ) {
      NSLog(@"Teacher Not Found in Database - %@\n", [sold Teacher_ID]);
      t1 = nil;
      } else {
      t1 = [results objectAtIndex:0];
      NSLog(@"Teacher[%ld] = %@\n", i, [t1 description]);
      }
    } else {
      [[NSApplication sharedApplication] presentError:error];
    }

    if ( (c != nil) && (t1 != nil) ) {
      [t1 addClasses_TaughtObject:c];
    }

    //    If I don't do this then the next time I search for the same
    Teacher_ID I get 0 results back...

    if (![moc save: &error]) {
      NSLog(@"Error while saving\n%@",[error description]);
      exit(1);
    }

    [c release], c = nil;
    }

    Any help figuring this out would be appreciated...

    Thanks
    Mike
  • Mike,

    > When I get to the first table that I need to recreate a one-to many
    > relationship I find that if after specifying the first connection if I
    > don't force a save of the managedObjectContext then the next fetch
    > that is for the index comes up with 0 results.  Here is part of my
    > code...

    It's a little hard to tell from the code excerpt that omits the
    definition of the fetch request, the relationships involved, etc. but
    my guess is that you're encountering a limitation of the in memory
    filtering that is applied to uncommitted changes.

    The -initWithEntity:insertIntoManagedObjectContext: method creates a
    new instance that is added to the list of pending insertions.  Those
    are committed during the next save.

    Executed a fetch request always goes to disk (searches the database)
    but the newly inserted objects haven't actually been saved yet.  So
    the database returns 0 results.  The NSManagedObjectContext notices
    it has a bunch of unsaved changes, and tries to adjust the results
    from the database query to accommodate the changes that have not yet
    been committed.

    This adjustment is done by applying the same predicate from the fetch
    request to each dirtied (unsaved) managed object of the entity you're
    fetching.  If the predicate matches the unsaved changes then inserted
    objects are added to the result set, deleted objects removed, etc.

    Since the filtering is only done to managed objects of the entity
    you're fetching, it's possible to fail to notice that changes to
    related objects would have affected the predicate.

    I infer from the excerpt that you're fetching Teachers.  The teacher
    objects ought to be marked dirty by:
        [t1 addClasses_TaughtObject:c];

    so examining your fetch request and your custom setter code would be helpful.
    --

    -Ben
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today