There is a problem with core data when a to-many relationship has no inverse. Changes made to the related property do not persist. This is a problem many of us have faced, as it can be found by googling.
This is to ask if some of you found a trick/workaround to achieve persistence, beside the obvious answer or adding an inverse relationship.
Background:
Example
In employees/department typical paradigm, if you have a huge number of employees able to belong to several departments, you need a to-many relationship from employee to department. You do not want the inverse because each time an employee is linked to a department, a (very) large NSSet must be loaded, updated and saved. Moreover if the department entity is never deleted, graph integrity is easy to maintain.
Please do not reply that this is a feature of core-data and that inverse relationship is mandatory. This is not stated as such and is more like a bug than a feature. Posting a bug report is not solving the point for current deployed systems.
Edit: The Join entity solution This edit is to give more light and discussion to Dan Shelly's answer proposal below.
First, to reply to your first, I'm not trying to have a many-to-many but a true unidirectional to-many. The very same page your linked has this text a bit below the one you quoted:
Unidirectional Relationships
It is not strictly necessary to model a relationship in both directions. In some cases it may be useful not to, for example when a to-many relationship may have a very large number of destination objects and you are rarely likely to traverse the relationship (you may want to ensure that you do not unnecessarily fault in a large number of objects at the destination of a relationship). Not modeling a relationship in both directions, however, imposes on you a great number of responsibilities, to ensure the consistency of the object graph, for change tracking, and for undo management.
That said your proposed solution of adding an join entity is a way to go if there is no solution to force core-data to generates and updates it automatically.
IMO, and for my use case, the join entity does not even need to have the relationship to Department. This to-one is useless and may be replaced by a property of the join entity keeping related Department information, like its objectID or other indexed property to reach it.
i.e:
DepartmentEmployee:
Properties: Dept_ix (integer)
Relationships: employee (to-one,nullify)
This is a great question.
ButFirst thing first:
It clearly state in the documentation:
"Important: You must define many-to-many relationships in both directions—that is, you must specify two relationships, each being the inverse of the other. You can’t just define a to-many relationship in one direction and try to use it as a many-to-many. If you do, you will end up with referential integrity problems."
Never the less, Lets describe the issue (resulting database)
When defining a to-many relationship, the resulting database does not add an additional table to map the relationship.
It only sets a property on the entity at one end of the to-many relationship equal to the last item that referenced it.
Example:
Model:
Entity: Department
Relationships: NONE
Properties: name (string)
Entity: Employee
Relationships: departments (to-many,no-action)
Properties: name
Resulting Database:
ZDEPARTMENT:
Z_PK
Z_ENT
Z_OPT
Z2DEPARTMENTS (int)
ZNAME
ZEMPLOYEE:
Z_PK
Z_ENT
Z_OPT
ZNAME
This structure will obviously result in data inconsistency.
The solution will be to hold an entity: DepartmentEmployee modeling the to-many relationship in both directions but one of them would be unidirectional (Department -> DepartmentEmployee):
DepartmentEmployee:
Relationships: department (to-one,no-action), employee (to-one,nullify)
and you will have to maintain the table upon deletion of a department object.
Hope this made some sense :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With