Need some info on how to set up core data migration with a new 1-to-many relationship - ios

Question regarding Core Data migrations:
The original model was just a single entity (Transaction) with multiple properties. The app could store N Transactions, and display them in a table.
Original Core Data Model (simplified):
Transaction:
property_x
property_y
property_z
The model has now been changed so that the new top-level entity is a TransactionsList entity, with a 1-to-many relationship so that each TransactionsList has multiple Transactions.
New Core Data Model (simplified):
TransactionsList:
property_a
property_b
transactions <-->> Transaction:
property_x
property_y
property_z
<- transactionList
The model has now been changed so that the top-level entity is a TransactionsList entity, with a 1-to-many relationship (transactions) so that each TransactionsList has multiple Transactions.
I'm having a problem finding any examples (either in Apple docs, or on the web) of how to set up a migration from the original configuration to this new configuration.
Lightweight migrations don't seem to work (since this change involves adding a new relationship).
I set up a mapping file, and tried to create a custom migration policy, but if I set breakpoints on any of the functions in it, they are never hit.
I turned on migration debugging, and it indicates that the migration succeeded:
"Automatic schema migration succeeded for store at "..."
However, if I look at the internals of the sqlite database, there are no database entries for the TransactionsList entity, and all the transactionList fields in the Transactions (which should be linked to the owning TransactionsList) are null.
Two questions...
1) Any clues as to why my custom entity migration policy might not be getting called
2) Any suggestions on the best way to set up this kind of migration?
Thanks.

You are correct that a light-weight migration will not work. Further, a heavy migration would be very expensive computationally and I would not advise it.
I recommend a two step approach:
Allow a light-weight migration to occur. This will cause your TransactionList entity to be empty.
After the migration, walk through your transactions and create TransactionList entities as appropriate.
This will be faster and easier to test/debug than using a heavy migration. You can test to see if a migration needs to occur using the -[NSManagedObjectModel isConfiguration: compatibleWithStoreMetadata:] method. This will let you know a migration is needed, then you kick off the migration and finally do the post processing.

Related

Core data versioning/migration after deleting entities

I have a database which consists of 3 entities, say
'IronMan', 'CaptainAmerica' and 'SpiderMan'.
With new changes, I want to delete all three entities and create another entity called 'Thanos'.
I would not need to use any of the code and data stored earlier with entities 'IronMan', 'CaptainAmerica' and 'SpiderMan'. Do I need to do core data versioning or migration in this case?
As mentioned in Apple's documentation
https://developer.apple.com/documentation/coredata/using_lightweight_migration
You can add, remove, and rename entities in the hierarchy.
So, yes, you need to provide migration (new version model) but can stick to a light-weight migration, hence it will be done automatically based on changes done between the 2 models.

How to actually execute CoreData heavyweight migration

I am performing a CoreData heavyweight migration in my app. I have created a mapping model, made associated NSEntityMigrationPolicy subclasses, and selected the new model as the current. However, the migration does not appear to be happening. What do I need to do for this to actually occur?
If your model is not eligible for lightweight migration, then you have to do it manually. Simply this process can explained as reading records from old store and dumping them in the new store according to new model.
See here and here for more details
You have to manually switch off the automatic migrations from persistent store coordinator so core data would not automatically infer mapping model and use your custom created model in core data stack.
key: NSInferMappingModelAutomaticallyOption
value: false

Execute a code after data model migration in Core Data (MagicalRecord)

I have to data models and a mapping model.
I would like to execute some code after the migration is done between my model v11 and model v12.
How can I do that? I'm using Magical Record.
I tried to do it in endEntityMapping from NSEntityMigrationPolicy, but it is an action that should be done after the entire migration, not in the middle.
Another idea I have is to save a flag in NSUserDefaults in any endEntityMapping and use it (and remove the flag) after my Core Data stack is setup by Magical Record, but this seems a bit workaround.

Move a Core Data entity and its data into new Core Data model file through Migration

Is it possible to move a Core Data entity Car and its data in Model1 into a new Core Data model Model2 using migration? Model2 will also have a new CarOwner entity + other new relationships (so model file is different than Model1). Is this possible using lightweight migration or do I have to use custom migration? I'm using Magical Record to setup my Core Data Stack.
I have been using lightweight migration for years with success. So I don't have any custom migration mechanism in place. I want to ask first before I implement a new system so I can incorporate CD custom migration into my existing MagicalRecord Core Data stack.
EDIT: updated question to clarify that Model1 and Model2 have differences.
With the same xcdatamodel file and different versions you can use a Mapping Model file, but being different mom files i guess those are different stacks and migration will not work.
Model migration is only relevant if the model has changed-- meaning, if the entities contained in the data model don't match the entities saved in the persistent store file. Migration doesn't depend on what model file you use, it depends on the entity hashes contained in that model.
Meaning: If your new model file has exactly the same entities as the persistent store file has, you don't actually need to migrate anything. Just start using the new model file. However keep in mind that if you ditch the old model file and all of its old versions, you won't be able to migrate from older versions of that model any more.

Optimistic Locking Exception using Grails GORM and MySQL

I am using Grails 2.4.4 and MySQL database. We are trying to clone a group of tables in our database having parent-child relationship. For example we have a table author with its child table book and book having foreign key fk_book pointing to author.
We retrieve the hierarchy through Author.get(id), the cloning author, its associated book and save using clonedAuthor.save(flush:true). We have hierarchy of several tables like this, some having OneToOne and some having OneToMany relationships. In database, the foreign key constraints are given as ON DELETE NO ACTION.
The problem is when invoked. It is throwing Optimistic Locking Failure Exception
Row was updated or deleted by another transaction.
I am not getting which transaction is updating the row since we have only one transaction (only one hit).
I was getting same problem when modifying db data using mysql console while some of the data is already fetched to the hibernate session.
why is this happening?
Just simple, the data in db and in hibernate session are out of sync.
Also if you are putting the domain object ( or any related domain object) in session try to re-attach the object(obj.attach()) before calling save,delete..
You have 3 solutions: merge() or attach() before save()... or mapping the entity with version false.

Resources