views:

897

answers:

5

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

A: 

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.
Tim
1. Not sure if i can evaluate error since the exception throws me out of the context.2. I started of only calling [context countForFetchRequest:request error: and that was when i experienced the issue.The executeFetchRequest and array.count was only thrown in there for sanity check.3. as per 2
Oskar
A: 

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:.

unforgiven
I realized i confused the question by having both countForFetchRequest and executeFetchRequest at the same time in my example.I never executed them both at the same time. I was only trying to show that one worked, and the other did not.
Oskar
A: 

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:].

Barry Wark
It's not nil. And executeFetchRequest works where countForFetchRequest fails.
Oskar
In that case, you may have found a Core Data bug. If you can reproduce this in a separate project with minimal other code, you should definitely submit a bug at bugreport.apple.com.
Barry Wark
A: 

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.

Elise van Looij
I tripple checked the entity name, and since executeFetchRequest performs fine the name is most likely right. I can live without the counting since thats solely for debug purpose.What I'm worried about though is that there is some underlying issue in my xcdatamodel that will come up and bite me some time down the road.
Oskar
+1  A: 

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

Ken Aspeslagh
Stopped getting the error by using setAffectedStores: on the request to point it to the store configured to contain the entity. A bug or do I not understand the purpose of configuration?
Ken Aspeslagh
I believe you solved the problem!I indeed had multiple stores.
Oskar
Since the normal fetch works and the count fails, I'd say this must be a bug, eh?
Ken Aspeslagh