Question

I'm experiencing a strange problem when trying to count the entities in a managed object context.

- (NSUInteger)countEntity:(NSString *)entityName 
                inContext:(NSManagedObjectContext *)context{

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName                     
                                                  inManagedObjectContext:context];
    [request setEntity:entity];
    [request setIncludesSubentities:NO];
    NSError *error = nil;
    NSUInteger count = [context countForFetchRequest:request error:&error];
    [request release];
    return count;
}

The line:

NSUInteger count = [context countForFetchRequest:request error:&error];

throws a NSInternalInconsistencyException reason: 'entity not found'

Changing to:

NSUInteger count = [[context executeFetchRequest:request error:&error] count];

works without any problem.

I'm at loss here. Any ideas?

Thanks!

/Oskar

Was it helpful?

Solution

Running into this today. Started happening when I introduced a second persistent store. Do you have more than one store in the moc? -Ken

OTHER TIPS

For what it's worth I've just come across a similar bug where executeFetchRequest:error and countForFetchRequest:error: don't agree on the number of objects in the fetch request.

The scenario is I have nested NSManagedObjectContexts with a root context of type NSPrivateQueueConcurrencyType (for saving to disk) backed by a persistent store and a child of that with type NSMainQueueConcurrencyType (for use by the gui). (Yes, I'm using MagicalRecord)

I have a ViewController listening to NSManagedObjectContextDidSaveNotification from the 'main' context. When that notification fires the countForFetchRequest:error: method does not include changes made in the context that haven't been saved in the parent root context. executeFetchRequest:error however returns the expected set of objects.

Bit wierd.

Check several things:

  1. What's the value of error after the first call? The reason you pass in that object is to get information out of it when things go wrong.
  2. What's the value of [request entity] after the first call? I may be completely off, but I very vaguely remember something about a request being a one-shot deal: once you execute it, you have to reset all the various fields before you can execute it again. Make sure all the properties of your request are still valid after the first call, or better yet create a second NSFetchRequest instance to perform the second call.
  3. In a similar vein, what happens if you comment the first call out? If you switch the order of the calls? The result of one could be affecting another.

I suspect that entity is nil (i.e. context is nil or does not have a correctly configured persistent store coordinator with a managed object model containing your entity, or you have misspelled the entity name somewhere in the object model or in the calling code). Verify that entity is not nil after the call to +[NSEntityDescription entityForName:inManagedObjectContext:].

I ran your method countEntity: in one of my own projects and it performed fine. The only way I could get it to throw an exception ("_countWithNoChangesForRequest:error: A fetch request must have an entity.") was when I mis-capitalized the name of the entity (widgets instead Widgets). So, you might want to investigate in that direction.

The issue you are experiencing is due to a wrong use of countForFetchRequest:error:. Indeed, in your code snippet you first execute the fetch request using executeFetchRequest:error, then proceed to use countForFetchRequest:error:.

From the method documentation:

Returns the number of objects a given fetch request would have returned if it had been passed to executeFetchRequest:error:.

Therefore you must NOT execute the fetch request before calling countForFetchRequest:error:.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top