I'm able to work with objects on a context and work with relationships. My registered objects are behaving correctly.
My store is added to the coordinator with the correct configuration (the configuration having 3 entities, one entity with the two other entities having a to-many relationship to the first entity).
Saving the store with either -many entity or with both -many entities works correctly. However, when I add the one- entity to the context, the object graph will not save.
It seems like it would be a common beginner's problem, but that means its also a difficult solution for beginners. I expect I'm not the first one to have run into this kind of trouble?
UPDATE: Thank you for the replies and pointers. It seems the main trouble is as subtly pointed out, that I am not handling errors properly. After looking at this post, Core Data Entity Relationship Does Not Save Between Launches , I have started improving with error handling. The localized description on this issue was 'ID required'. While I still don't know what that means, I can at least have the chance to figure it out, now.
To-Many relationships are represented as sets on the object. So child ->> parent implies that child.parent is represented as a set. Therefore, when you add a new parent object, you need to add that parent object to the set before you save the context. If you say self.parent = inserted_parent_object, I am not sure what would happen. If you are going the other way around it is easier. When you insert the parent object, just set the child (assuming you have it) and save the context. That will work unless it is a many to many relationship.
If there is an error, the code and the error message would be helpful in order to help you debug.
This one has code:
CoreData adding relationships to-many
Related
I have a Core Data model that includes Document Entities and Quote Entities. There is a many-Quotes-to-one-Document Relationship in the model.
I am introducing a new type of Quote, so I would like to create a parent BaseQuote Entity, that will have TextQuote and ImageQuote 'child' Entities. The existing Quote will become a TextQuote.
So, I need to push the Quote side of the Relationship down the hierarchy into BaseQuote.
The lightweight migration documentation says that I can manage "changes to hierarchies" and "changes to relationships", but is not clear that it handles both at once!
If I check the mapping, Core Data thinks it is possible, inferredMappingModel does not throw an error:
NSMappingModel.inferredMappingModel(forSourceModel: lastVersion, destinationModel: thisVersion)
However, when I run the migration I get a crash with the message:
Validation error missing attribute values on mandatory destination relationship
It turns out the relationship is not being correctly populated by the migration - although structurally it seems to have worked.
Has anyone tried this before and got it working?
I think this is beyond lightweight migration. The page you link to explains that relationship changes include adding, deleting, renaming, and changing to-one to to-many or back. What you need is to move the relationship from one entity to a different one in the hierarchy, that is, take a relationship to Quote and move it to the new BaseQuote. It would probably be fine if you were changing the hierarchy and making one of those changes (renaming the relationship, for example). Lightweight migration doesn't cover re-targeting a relationship to a different part of the hierarchy, though.
I'm trying to start an application and my idea was to rattle off the entities first using the command line and then work on the UI. This is proving trickier than I first thought because under certain circumstances you get a warning saying the generator won't work. It's things like whether it's a OneToMany or a ManyToOne or whether this entity is the owning side of the relationship.
What's the best way around this?
If I can work out the rules then I can maybe decide what order to create things in. My worry is that with a complicated schema there is no order that can work without some warnings and things not working.
My other idea was to generate the entities without relationships first and then edit the json files to add the relationships. Then maybe I can run the generator again on each entity. Not sure if that would work though and I'm not 100% sure of the correct json properties required.
What have other people tried?
Plan your entities and relationships, so that when you create an entity all the entities it depends on have already been created. One way to do this is use a schema designer or just document the entities and put them in the order they need to be created.
Otherwise, as you know, you'll have to manually wire those relationships, or recreate them with the entity generator.
But, even with planning, you're going to have to use a mixture of these methods in the real world. It just depends on how much you've modified the generated code as to which method is the fastest.
Rori's answer is basically what I did but I wanted to provide some extra detail.
First I went through the generator and created every type of relationship to see which ones worked and which ones gave a warning. I was finding that sometimes it worked and sometimes it didn't but it wasn't documented anywhere why.
These relationships always work.
OneToMany
OneToOne (not owner)
ManyToMany (not owner)
These relationships only work when the other entity already exists.
ManyToOne
OneToOne (owner)
ManyToMany (owner)
The reason they don't work is always the same. All of these require a foreign key to be created on the other table which jHipster can't do if it doesn't exist yet. You could of course ignore the warning but I wasn't sure if this meant anything else wouldn't work.
Based on these rules I made a list of my entities and put them into an order that would work without warnings. If an entity had a relationship that may give a warning then I just made sure the other entity was created first.
This seems to have worked. The only thing I've found is that because the generator is a one time thing (you can't use it to modify an entity), you have to know your schema up front and generate the lot in one go.
I´m a little confused about inheritance and relationships in core data, and I was hopping someone could drive to the right path. In my app i have created 3 entities, and none of them have (and are not suppose to have) common properties, but there´s gonna be a save and a load button for all the work that the user does. From my understanding I need to "wrap" all the entities "work" into an object which will be used to save and load, and my question is, do I need to create relationships between the entities? Because I have to relate them somehow and this is what make sense to me. Is my logic correct?
I'm implementing a budget calculator, and for the purpose of everyone understand what my issue is, I´m going to give an practical example and please correct me if my logic is incorrect:
Let´s just say you are a fruit seller, and because of that it´s normal to have a database of clients and also a fruit database with the kinds of fruit you sell. From my understanding I find two entities here:
Client with properties named: name, address, phone, email, etc.
Stock with properties named: name, weight, stock, cost, supplier, etc.
TheBudget with properties named: name, amount, type, cost, delivery, etc.
I didn´t put all the properties because I think you get the point. I mean as you can see, there´s only two properties I could inherit; the rest is different. So, if I was doing a budget for a client, I can have as many clients I want and also the amount of stock, but what about the actual budget?
I´m sorry if my explanation was not very clear, but if it was..what kind of relationships should I be creating? I think Client and TheBudget have a connection. What do you advise me?
That's not entirely correct, but some parts are on the right track. I've broken your question down into three parts: relationships, inheritance and the Managed Object Context to hopefully help you understand each part separately:
Relationships
Relationships are usually used to indicate that one entity can 'belong' to another (i.e. an employee can belong to a company). You can setup multiple one-to-many relationships (i.e. an employee belongs to a company and a boss) and you can setup the inverse relationships (which is better described with the word 'owns' or 'has', such as 'one company has many employees).
There are many even more complicated relationships depending on your needs and a whole set of delete rules that you can tell the system to follow when an entity in a relationship is deleted. When first starting out I found it easiest to stick with one-to-one and one-to-many relationships like I've described above.
Inheritance
Inheritance is best described as a sort of base template that is used for other, more specific entities. You are correct in stating that you could use inheritance as a sort of protocol to define some basic attributes that are common across a number of entities. A good example of this would be having a base class 'Employee' with attributes 'name', 'address' and 'start date'. You could then create other entities that inherit from this Employee entity, such as 'Marketing Rep', 'HR', 'Sales Rep', etc. which all have the common attributes 'name', 'address' and 'start date' without creating those attributes on each individual entity. Then, if you wanted to update your model and add, delete or modify a common attribute, you could do so on the parent entity and all of its children will inherit those changes automatically.
Managed Object Context (i.e. saving)
Now, onto the other part of your question/statement: wrapping all of your entities into an object which will be used to save and load. You do not need to create this object, core data uses the NSManagedObjectContext (MOC for short) specifically for this purpose. The MOC is tasked with keeping track of objects you create, delete and modify. In order to save your changes, you simply call the save: method on your MOC.
If you post your entities and what they do, I might be able to help make suggestions on ways to set it up in core data. You want to do your best to setup as robust a core data model as you can during the initial development process. The OS needs to be able to 'upgrade' the backing store to incorporate any changes you've made between your core data model revisions. If you do a poor job of setting up your core data model initially and release your code that way, it can be very difficult to try and make a complicated model update when the app is in the wild (as you've probably guessed, this is advice born out of painful experience :)
I'm running into an issue with my core data model. I would like to have an entity called TherapySession have two Mood events - start and end. To do so I've defined two relationships to child objects:
However, I would also like to create an inverse relationship, where each Mood object would be aware of it's parent therapy session. I'm not sure how to properly create the inverse relationship between the child and parent object when there are more than one relationship of the same type defined. In my case, the inverse relationship points to the "startMood" property of the therapy session:
It seems that I'm doing something wrong, but I cannot put my finger on how to resolve this problem. If I add an end mood to therapy, and the core data would try to create an inverse relationship, would it overwrite the startMood relationship?
Thank you for any clarifications! I know that this can be avoided by adding a set of objects, and then sorting the set by date, but I would like to avoid having to do that for every object.
One solution is to stick with a simple many-to-one relationship mood and an additional attribute in entity Mood that indicates start or end.
This is also more flexible - in the future it would be trivial to introduce more moods at different therapy points etc. without having to change the data model.
I'm not sure if this is the right way to do this, but I always end up creating two inverse relationships, like startMoodInverse and endMoodInverse. (You can then add a property in code that returns whichever of those is non-nil as therapySession.)
I've got a simple pojo named "Parent" which contains a collection of object "Child".
In hibernate/jpa, it's simply a one-to-many association, children do not know their parent: these Child objects can have different type of Parent so it easier to not know the parent (think of Child which represents Tags and parents can be different object types which have tags).
Now, I send my Parent object to the client view of my web site to allow user to modify it.
For it, I use Hibernate/GWT/Gilead.
My user mades some changes and click the save button (ajax) which sends my Parent object to the server. fields of my parent has been modified but more important, some Child objects has been added or deleted in the collection.
To summary, when Parent object comes back to server, it now has in its collection:
- new "Child" objects where id is null and need to be persist
- modified "Child" objects where id is not null and need to be merge
- potentially hacked "Child" objects where id is not null but are not originally owned by the Parent
- Child objects missing (deleted): need to be deleted
How do you save the parent object (and its collection) ? do you load the parent collection from database to compare each objects of the modified collection to see if there is no hacked item ?
Do you clear the old collection (to remove orphan) and re add new child (but there is some Child that has not been modified) ?
thanks
PS: sorry for my english, I hope you have understand the concept ;)
Something in your stack has to supply the logic you are talking about, and given your circumstances it is probably you. You will have to get the current persisted state of the object by reading from your datasource so you can do the comparison. Bear in mind that, if several legitimate actions can update your parent object and its collection simultaneously you will have to take great care over defining your transaction grain and the thread-safe nature of your code.
This is not a simple problem by any means and there may well be framework features that can assist, but I am yet to find something which has solved this for any real world implementation I have encountered, especially where I have logic which tried to distinguish between legitimate and "hacked" data.
You may consider altering your architecture such that the parent and children are persisted in separate actions. It may not be appropriate in your case but you might be able to have a finer grain of transaction by splitting up the persistence actions and provide child-oriented security which makes your problem of hacking a little more manageable.
Good luck. I recommend you draw a detailed flow chart of your logic before you do too much coding.
The best solution I've found is to manage a DTO, manually created. The DTO sends only needed datas to the client. For each fields I want to set in ReadOnly mode, I calculate a signature based on a secret key that I send to client with my dto.
When my DTO comes back to server, I check the signature to be sure that my read only fields have not changed (recalculate the signature with coming back fields and compare it to the signature coming back with dto)
It allows me to specify read only fields and be sure that my objects are not hacked.