A unique instance of an object that supports streams in master data

I have a Message object that has a messageID property. I would like to make sure that there is only one instance of the Message object with the given messageID. In SQL, I would simply add a unique constraint to the messageID column, but I don't know how to do this with Core Data. I don’t think it can be done in the data model itself, so how do you do it?

My initial thought was to use a validation method to fetch in the context of an NSManagedObject for an identifier, see if it finds anything other than itself, and if so, the validation fails. I suspect this will work, but I'm worried about the performance of something like that. I made a lot of efforts to minimize the sample requests needed for the entire import procedure, and checking it by fetching for each individual message object seems a bit overwhelming. I can get all the pre-existing objects that I need and identify all the new objects that I need to insert into the repository using only two fetch requests before I do the actual work of importing and connecting everything together. This would add a selection for each individual update or insert in addition to the two, which would seem to eliminate any performance advantage that I had in the pre-processing of import data in the first place!

The main reason is that the importer can (potentially) run several batches simultaneously on several streams and may include some duplicate / duplicate data, which ultimately should lead to only one object in the storage, and not duplicate records. Is there any reasonable way to do this and do what I ask to make sense for Core Data?

+4
source share
4 answers

The only way to guarantee uniqueness is to make a selection. Fortunately, you can just do -countForFetchRequest:error: and check if it is zero or not. This is the least expensive way to guarantee uniqueness at the moment.

Perhaps you can do this while checking or run it in a data processing loop. Personally, I would do this on creating an NSManagedObject so that you don't have unnecessary allocations when the record already exists.

+3
source

I don’t think there is a way to easily ensure that an attribute is unique without doing a lot of work on its own. You can, of course, use CFUUIDCreate to create a globally unique UUID that must be unique even in a multi-threaded environment. But...

objectID (type NSManagedObjectID ) of all managed objects is guaranteed to be unique in the persistent storage coordinator. Since you can add arbitrarily many persistent stores to the coordinator, this guarantee basically ensures that objectID are globally unique. Why aren't you using objectID as your messageID? Of course, you cannot change the objectID after its assignment (and it will not be assigned until the context containing the inserted object is saved, until it is temporary, but still unique identifier).

+1
source

So, you have an NSManagedContext for each thread supported by the same persistent storage, is that correct? And before you save the NSManagedContext, you need to make sure that the messageID is unique, that is, that you are not updating the existing string and that it is not in one of the other contexts, right?

Given this model (correct me if I misunderstood), I think you will be better off serving one object that controls access to persistent storage. That way, all threads will update the same context, and you can do your check there using the Marcus -countForFetchRequest:error: . Of course, this puts a narrow band in this operation.

+1
source

Just add my 2 cents: I think the inconsistencies will come up sooner or later anyway, and the only way to mitigate them is to do this at the application level with fairly complex code.

So, in my case, I decided to allow duplicate values ​​for what should be "unique."

I added code that later detects these problems (for example, when a selection that should return 1 object returns more than 1) and corrects them when they occur (usually by deleting).

It is "going forward, making a mistake, fixing it later for you." Strategy.

This is not ideal, of course, but the right way to attack this problem is imho.

0
source

Source: https://habr.com/ru/post/1300007/


All Articles