Core Data -existingObjectWithID:error: causes error 133000

Jean-Denis Muys picture Jean-Denis Muys · Dec 26, 2011 · Viewed 9.1k times · Source

My app uses Core Data (with some help of Magical Record) and is rather heavily multithreaded using NSOperation.

Of course I am very careful to only pass around NSManagedObjectID between threads/operations.

Now, to get back to the corresponding managed object in an operation, I use -existingObjectWithID:error: thus:

Collection *owner = (Collection *)[localContext existingObjectWithID:self.containerId error:&error];

But what I get back is nil and error says this is an error #13300: NSManagedObjectReferentialIntegrityError.

Here is what the documentation says about this error:

NSManagedObjectReferentialIntegrityError
Error code to denote an attempt to fire a fault pointing to an object that does not exist.
The store is accessible, but the object corresponding to the fault cannot be found.

Which is not true in my case: that object exists. Indeed, If I iterate through all instances of that Collection entity with an NSFetchRequest, I find it among them, and its NSManagedObjectID is exactly the one I passed to -existingObjectWithID:error:.

Moreover, if I use -objectWithID: instead, I get a correct object back just fine.

So there is something I'm missing. Here are a few additional observations/questions:

  • "an object that does not exist": what it the meaning of "exist" in that sentence? "exist" where? It definitely "exists" in my Core Data store at that point.
  • "the object corresponding to the fault cannot be found": what it the meaning of "found" in that sentence? "found" where? It definitely "be found" in my Core Data store at that point.

So maybe I am missing something regarding what existingObjectWithID:error: does? The documentation says:

If there is a managed object with the given ID already registered in the context, that object is returned directly; otherwise the corresponding object is faulted into the context.
[...]
Unlike objectWithID:, this method never returns a fault.

This doesn't help my issue. I don't mind getting my object fully faulted, and not a fault. In fact, any fault within it will fire on the next code line when I access the object properties.

  • What would be a realistic scenario leading to an NSManagedObjectReferentialIntegrityError?

Thanks for any enlightenment.

Answer

Alexey Kozhevnikov picture Alexey Kozhevnikov · Feb 20, 2014

The problem is that NSManagedObjectID you pass is temporary. You can check it by calling NSManagedObjectID's isTemporaryID method. From docs:

Returns a Boolean value that indicates whether the receiver is temporary.

Most object IDs return NO. New objects inserted into a managed object context are assigned a temporary ID which is replaced with a permanent one once the object gets saved to a persistent store.

You should first save your changes to persistent store, only then get a permanent ID to pass to other context.