In DDD, how do you handle a conceptual object that is somewhere between an Entity and a Value Object? - entity

In your domain model, how do you treat a conceptual object that is somewhere between an Entity and a Value Object? I.e, it is not small; it has many attributes, but it also doesn't have any identity or meaning in-and-of itself (i.e. equality is based on attributes). Because it needs to have its attributes edited via the UI, I can't see how it can be made immutable--constantly being destroyed and recreated every time the user changes an attribute. Furthermore, this hybrid object is intended to become an entity of either one type or another, depending on its role in the system.
Example: a Recipe class. Its purpose is to encapsulate a set of instructions to be carried out by a machine. Two different recipe objects are equal if their collective instructions are identical. A Recipe is intended to take on two Entity roles in the system:
To be used in a MasterSequence, which is simply a list of Recipe
objects that get executed in sequential order. In this case the
Recipe would conceptually take on addition attributes such as
StepNumber and IsActive. Each of these recipies now carries an
identity (i.e. the Recipe in step 1 might have identical attributes
to the one in step 2, but they are conceptually distinct).
A Recipe can be saved as a "Favorite Recipe" that is persisted in a
favorites list. In this case the Recipe has no concept of StepNumber
or IsActive, but rather, a simple ID that gives it its identity.
In either of these two roles, the UI needs to present a dialog box to edit the attributes of the underlying recipe.
So should two entities be created, SequencedRecipe and FavoriteRecipe that act as wrappers to a Recipe object? And should the Recipe take on all the semantics of a Value Object, considering its size/complexity and need for editing?

I think you miss something in your ubiquitous language to distinguish between the idea of a recipe, i.e. its blueprint, and a real recipe as executed in a MasterSequence.
The concept of Prototype (and design pattern by the same name) might be helpful here.
The RecipePrototype Entity would be able to spawn a new Recipe VO when needed. This VO would then be incorporated in the MasterSequence -- this way, if the original Recipe blueprint is changed, it won't affect existing MasterSequences using this recipe.
public class RecipePrototype {
// all your recipe fields here
public Recipe spawnRecipe() {
// copy yourself and return a new Recipe VO here
}
}
A Favorite Recipe would simply be a reference to a RecipePrototype ID.
Edit : from the latest comments I now realize that Recipes contained in MasterSequence are not a specific kind of Recipe with a life of their own, and the original Recipe object is always what gets modified.
Thus, Recipe is clearly an Entity to me, there's no Value Object modification involved whatsoever.
This becomes a UI problem -- you just need to have two different ViewModels (MasterSequenceRecipe and FavoriteRecipe) for display but map to the same domain action in modification -- changing a Recipe entity.

I actually think Recipe is an entity because it sounds like it does have an identity in actuality. You say if 2 recipes have the same values then they are the same. Then you speak of editing those recipes in the UI. How would you reference the recipe that got updated? I doubt you would update any random recipe in the system that matches all the same attributes. It sounds like you would need a recipe ID of some kind, since you do care which recipe was edited, even if the attributes happen to be the same. Favorite recipe would simply reference the recipe by ID as well, or any other entity that had a recipe or sequence of recipes associated with it.

Related

How to organize Core Data entities that have circular dependencies?

This is a conceptual question about how best to organize relationships between NSManagedObjects in Core Data.
How do you organize your entities in Core Data when there appear to be circular dependencies?
For example, let's say I'm doing a social recipe app. This app allows you to organize meals based on who's making each recipe and who's buying each ingredient. In addition, each recipe is created by a different person. I thus propose the following NSManagedObjects followed by their respective attributes and relationships:
Chef = uniqueID (String), username (String), skill (String)
>> recipesToMake = (to-many) Recipe
>> ingredientsToBuy = (to-many) Ingredient
Recipe = uniqueTitle (String), authorID (String)
>> ingredients = (to-many) Ingredient
Ingredient = name (String), calories (Integer 64)
QUESTIONS
[_] If I have multiple Chef's working on the same recipe, does that mean multiple copies of the same Recipe object are stored in Core Data, each belonging to a separate Chef? If so, is that alright? If not, how to I go about making a single Recipe object in Core Data and having multiple Chef's point to it, when Chef itself can point to-many Recipe objects via recipesToMake?
[_] If given a recipe, how would I check which Chef's are assigned to it? Would I fetch those Chef objects in Core Data that point to a Recipe object with the given uniqueTitle attribute?
[_] Since a Chef object can point to-many Recipe objects, is it thus correct to store the author of each Recipe as an attribute on Recipe containing the author's uniqueID? I initially would have thought to create a relationship from Recipe to-one Chef, but that then creates yet another circular dependency between Chef and Recipe objects.
[_] Yet again, if Chef can point to-many Ingredient objects via ingredientsToBuy and Recipe can point to-many Ingredient objects via ingredients, does that many there will be multiple copies of the same Ingredient object in CoreData?
[_] If I were to allow Recipe objects to have an arbitrary number of authors, how would I go about implementing that? Using a relationship with Chef objects would seem to create a circular dependency, while using attributes connected to Chef uniqueID's would seem to require pre-specifying a maximum number of authors per Recipe object.
The term "circular dependency" is used negatively here, but what you are really referring to in Core Data is relationships and inverse relationships, and its actually recommended.
Circular dependencies are unwanted when you are architecting a system of classes that rely on each other too much and in both directions, also known as coupling. They are indeed not desirable, but it relates more to code flow and logic, not when dealing with data relationships.
Here are answers to your questions:
The onus is on you to the enforce uniqueness of Recipes in your code, which means you have to define the qualities that make two recipes the "same" recipe. You can go so far as to compare each Ingredient of the recipe, or it may suffice that the uniqueTitle is all thats needed to compare for uniqueness of recipe. With that, you can implement the "update or create" design pattern, where you first look up the Recipe by its primary key, which in the simpler scenario is the uniqueTitle. If it already exists, then you can simply read and/or update that object. Otherwise create it as a new managed object. Subsequent queries for it will fetch the just-created object. Each chef then can have a relationship to that single Recipe object.
For every relationship, it's a good practice to also define the inverse relationship. In the Recipe object, call it something like "ChefsMaking", which is probably a to-many relationship that points to Chef objects. (They combine to make a "many-to-many" relationship). In Xcode, theres a drop down box for each relationship where you can set up its inverse.
I do believe its possible to create more than one relationship that references the same type of object. Here there are two types of relationship that point from Recipe to Chef. One is "ChefsMaking", a to-many relationship. The other is "Author", a to-one relationship, the inverse of which would be a to-many "RecipesAuthored" relationship in the Chef object.
The same principles from answer 1 apply here. Define uniqueness of an Ingredient, and have your Chefs and Recipes point to an Ingredient either by fetching one that already exists (by its primary key) or creating a new one.
Simply rename your relationship Authors, and make it a to-many relationship.
Hope this helps!

How does one architect an entity in Core Data with a generic relationship?

Say you need to architect an app with an entity that can be associated with multiple other kinds of entities. For example, you have a Picture entity that can be associated with a Meal entity, a Person entity, a Boardroom entity, a Furniture entity, etc. I can think of a number of different ways to address this problem, but -- perhaps because I'm new to Core Data -- I'm not comfortable with any of them.
The most obvious approach that comes to mind is simply creating a relationship between Picture and each entity that supports associated pictures, but this seems sloppy since pictures will have multiple "null pointers."
Another possibility is creating a superentity -- Pictureable -- or something. Every entity that supports associated pictures would be a subentity of Pictureable, and Picture itself would have a one-to-one with Pictureable. I find this approach troubling because it can't be used more than once in the context of a project (since Core Data doesn't support multiple inheritance) AND the way Core Data seems to create one table for any given root entity -- assuming a SQLite backing -- has me afeard of grouping a whole bunch of disparate subentities under the umbrella of a common superentity (I realize that thinking along these lines may smack of premature optimization, so let me know if I'm being a ninny).
A third approach is to create a composite key for Picture that consists of a "type" and a "UID." Assuming every entity in my data model has a UID, I can use this key to derive an associated managed object from a Picture instance and vice versa. This approach worries me because it sounds like it might get slow when fetching en masse; it also doesn't feel native enough to me.
A fourth approach -- the one I'm leaning towards for the app I'm working on -- is creating subentities for both Picture and X (where X is either Meal, Person, Boardroom, etc.) and creating a one-to-one between both of those subentities. While this approach seems like the lesser of all evils, it still seems abstruse to my untrained eye, so I wonder if there's a better way.
Edit 1: In the last paragraph, I meant to say I'm leaning towards creating subentities just for Picture, not both Picture and X.
I think the best variations on this theme are (not necessarily in order):
Use separate entities for the pictures associated with Meal, Person, Boardroom, etc. Those entities might all have the same attributes, and they might in fact all be implemented using the same class. There's nothing wrong with that, and it makes it simple to have a bidirectional relationship between each kind of entity and the entity that stores its picture.
Make the picture an attribute of each of the entity types rather than a separate entity. This isn't a great plan with respect to efficiency if you're storing the actual picture data in the database, but it'd be fine if you store the image as a separate file and store the path to that file in an attribute. If the images or the number of records is small, it may not really be a problem even if you do store the image data in the database.
Use a single entity for all the pictures but omit the inverse relationship back to the associated entity. There's a helpful SO question that considers this, and the accepted answer links to the even more helpful Unidirectional Relationships section of the docs. This can be a nice solution to your problem if you don't need the picture->owner relationship, but you should understand the possible risk before you go down that road.
Give your picture entity separate relationships for each possible kind of owner, as you described in the first option you listed. If you'll need to be able to access all the pictures as a group and you need a relationship from the picture back to its owner, and if the number of possible owner entities is relatively small, this might be your best option even if it seems sloppy to have empty attributes.
As you noticed, when you use inheritance with your entities, all the sub-entities end up together in one big table. So, your fourth option (using sub-entities for each kind of picture) is similar under the hood to your first option.
Thinking more about this question, I'm inclined toward using entity inheritance to create subentities for the pictures associated with each type of owner entity. The Picture entity would store just the data that's associated with any picture. Each subentity, like MealPicture and PersonPicture, would add a relationship to it's own particular sort of owner. This way, you get bidirectional Meal<->MealPicture and Person<->PersonPicture relationships, and because each subentity inherits all the common Picture stuff you avoid the DRY violation that was bugging you. In short, you get most of the best parts of options 1 and 3 above. Under the hood, Core Data manages the pictures as in option 4 above, but in use each of the picture subentities only exposes a single relationship.
Just to expand a bit on Caleb's excellent summation...
I think it's important not to over emphasize the similarities between entities and classes. Both are abstractions that help define concrete objects but entities are very "lightweight" compared to classes. For one thing, entities don't have behaviors but just properties. For another, they exist purely to provide other concrete objects e.g. managed object context and persistent stores, a description of the data model so those concrete objects can piece everything together.
In fact, under the hood, there is no NSEntity class, there is only an NSEnitity***Description*** class. Entities are really just descriptions of how the objects in an object graph will fit together. As such, you really don't get all the overhead an inefficiency of multiplying classes when you multiply entities e.g. having a bunch of largely duplicate entities doesn't slow down the app, use more memory, interfere with method chains etc.
So, don't be afraid to use multiple seemingly redundant entities when that is the simplest solution. In Core Data, that is often the most elegant solution.
I am struggling with esactly this dilemma right now. I have many different entities in my model that can be "quantified". Say I have Apple, Pear, Farmer for all of those Entities, I need a AppleStack, PearStack, FarmerGroup, which are all just object+number. I need a generic approach to this because I want to support it in a model editor I am writing, so I decided I will define a ObjectValue abstract entity with attributes object, value. Then I will create child entities of ObjectValue and will subclass them and declare a valueEntity constant. this way I define it only once and I can write generic code that, for example, returns the possible values of the object relationship. Moreover if I need special attributes (and I actually do for a few of those) I can still add them in the child entities.

How to bind an NSTableView to multiple core data entity types

I'm writing an application to help diabetics manage their condition. Information that is tracked includes blood sugar results, nutrition, exercise, and medication information.
In similar applications these entries are all presented in a single table view even though each type of entry has different fields. This data is manually tracked by many diabetics in a logbook, and I'm looking to keep that paradigm.
Each entry has some common information (timestamp, category, and notes) as well as information specific to each entry type. For instance, meal entries would have detailed nutrition information (carb counts, fiber, fat, etc), medication entries would indicate which medication and dosage, etc.
I've considered two different approaches but I'm getting stuck at both a conceptual level and a technical level when attempting to implement either. The first approach was to create an abstract entity to contain all the common fields and then create entities for each log entry type (meals, meds, bg, etc.) that are parented to the abstract entity. I had this all modeled out but couldn't quite figure out how to bind these items to an array controller to have them show up in a single table view.
The second approach is to have one entity that contains the common fields, and then model the specific entry types as separate entities that have a relationship back to the common record (sort of like a decorator pattern). This was somewhat easier to build the UI for (at least for the common field entity), but I come to the same problem when wanting to bind the specific data entities.
Of course the easiest approach is to just throw all the fields from each different entry type into one entity but that goes against all my sensibilities. And it seems I would still run into a similar problem when I go to bind things to the table view.
My end goal is to provide an interface to the user that shows each entry in chronological order in a unified interface instead of having to keep a separate list of each entry type. I'm fine with adding code where needed, but I'd like to use the bindings as much as possible.
Thanks in advance for any advice.
Don't get bogged down with entity inheritance. You shouldn't use it save duplicate attributes like you would with classes. It's major use is allow different entities to be in the same relationship. Also, entity inheritance and class inheritance don't have to overlap. You can have a class inheritance hierarchy without an entity inheritance hierarchy.
I'm not sure I understand exactly what you really need but here's some generic advice: You shouldn't create your data model based on the needs of the UI. The data model is really a simulation of the real-world objects, events or conditions that your app deals with. You should create your data model first and foremost to accurately simulate the data. Ideally, you should create a data model that could be used with any UI e.g. command-line, GUI, web page etc.
Once your model is accurately setup, then whipping up the UI is usually easy.

how to model value object relationships?

context:
I have an entity Book. A book can have one or more Descriptions. Descriptions are value objects.
problem:
A description can be more specific than another description. Eg if a description contains the content of the book and how the cover looks it is more specific than a description that only discusses how the cover looks. I don't know how to model this and how to have the repository save it. It is not the responsibility of the book nor of the book description to know these relationships. Some other object can handle this and then ask the repository to save the relationships. But BookRepository.addMoreSpecificDescription(Description, MoreSpecificDescription) seems difficult for the repository to save.
How is such a thing handled in DDD?
The other two answers are one direction (+1 btw). I am coming in after your edit to the original question, so here are my two cents...
I define a Value Object as an object with two or more properties that can (and is) shared amongst other entities. They can be shared only within a single Aggregate Root, that's fine too. Just the fact that they can (and are) shared.
To use your example, you define a "Description" as a Value Object. That tells me that "Description" with multiple properties can be shared amongst several Books. In the real-world, that does not make sense as we all know each book has unique descriptions written by the master of who authored or published the book. Hehe. So, I would argue that Descriptions aren't really Value Objects, but themselves are additional Entity objects within your Book Aggregate Root Entity boundery (you can have multiple entities within a single aggregate root's entity). Even books that are re-released, a newer revision, etc have slightly different descriptions describing that slight change.
I believe that answers your question - make the descriptions entity objects and protect them behind your main Book Entity Aggregate Root (e.g. Book.GetDescriptions()...). The rest of this answer addresses how I handle Value Objects in Repositories, for others reading this post...
For storing Value Objects in a repository, and retrieving them, we start to encroach onto the same territory I wrestled with myself when I went switched from a "Database-first" modeling approach to a DDD approach. I myself wreslted with this one, on how to store a Value Object in the DB, and retrieve it without an Identity. Until I stepped back and realized what i was doing...
In Domain Driven Design, you are modeling the Value Objects in your domain - not your data store. That is the key phrase. It means you are not designing the Value Objects to be stored as independant objects in the data store, you can store them however you like!
Let's take the common DDD example of Value Objects, that being an Address(). DDD presents that an Mailing Address is the perfect Value Object example, as the definition of a Value Object is an object of who's properties sum up to create the uniqueness of the object. If a property changes, it will be a different Value Object. And the same Value Object 9teh sum of its properties) can be shared amongst other Entities.
A Mailing Address is a location, a long/lat of a specific location on the planet. Multiple people can live at the address, and when someone moves, the new people to occupy the same Mailing Address now use the same Value Object.
So, I have a Person() object with a MailingAddress() object that has the address information in it. It is protected behind my Person() aggregate root with get/update/create methods/services.
Now, how do we store that and share it amongst the people in the same household? Ah, there lies DDD - you aren't modeling your data store straight from your DDD (even though, that would be nice). With that said, you simple create a single Table that presents your Person object, and it has the columns for your mailing address within it. It is the job of your Repository to re-hydrate that information back into your Person() and MailingAddress() object from the data store, and to split it up during the Create/Update operations.
Yep, you'd have duplicate data now in your data store. Three Person() entities with the same mailing address all now have three seperate copies of that Value Object data - and that is ok! Value Objects are meant to be copied and destoyed quite easily. "Copy" is the optimum word there in the DDD playbook.
So to sum up, Domain Drive Design is about modeling your Domain to represent your actual business use of the objects. You model a Person() entity and a MailingAddress Value Object seperately, as they are represented differently in your application. You persist them a copied-data, that being additional columns in the same table as your Person table.
All of the above is strict-DDD. But, DDD is meant to be just "suggestions", not rules to live by. That's why you are free to do what myself and many others have done, kind of a loose-DDD style. If you don't like the copied data, your only option is that being you can create a seperate table for MailingAddress() and stick an Identity column on it, and update your MailingAddress() object to have now have that identity on it - knowing you only use that identity to link it to other Person() objects that share it (I personally like a 3rd many-to-many relationship table, to keep the speed of the queries up). You would mask that Idenity (i.e. internal modifier) from being exposed outside of your Aggregate Root/Domain, so other layers (such as the Application or UI) do not know of the Identity column of the MailingAddress, if possible. Also, I would create a dedicated Repository just for MailingAddress, and use your PersonService layer to combine them into the correct object, Person.MailingAddress().
Sorry for the rant... :)
First, I think that reviews should be entities.
Second, why are you trying to model relationships between reviews? I don't see a natural relationship between them. "More specific than" is too vague to be useful as a relationship.
If you're having difficulty modeling the situation, that suggests that maybe there is no relationship.
I agree with Jason. I don't know what your rationale is for making reviews value objects.
I would expect a BookReview to have BookReviewContentItems so that you could have a method on the BookReview to call to decide if it is specific enough, where the method decides based on querying its collection of content items.

Does every Core Data Relationship have to have an Inverse?

Let's say I have two Entity classes: SocialApp and SocialAppType
In SocialApp I have one Attribute: appURL and one Relationship: type.
In SocialAppType I have three Attributes: baseURL, name and favicon.
The destination of the SocialApp relationship type is a single record in SocialAppType.
As an example, for multiple Flickr accounts, there would be a number of SocialApp records, with each record holding a link to a person's account. There would be one SocialAppType record for the "Flickr" type, that all SocialApp records would point to.
When I build an application with this schema, I get a warning that there is no inverse relationship between SocialAppType and SocialApp.
/Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse
Do I need an inverse, and why?
Apple documentation has an great example that suggest a situation where you might have problems by not having an inverse relationship. Let's map it into this case.
Assume you modeled it as follows:
Note you have a to-one relationship called "type", from SocialApp to SocialAppType. The relationship is non-optional and has a "deny" delete rule.
Now consider the following:
SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated
[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];
BOOL saved = [managedObjectContext save:&error];
What we expect is to fail this context save since we have set the delete rule as Deny while relationship is non optional.
But here the save succeeds.
The reason is that we haven't set an inverse relationship. Because of that, the socialApp instance does not get marked as changed when appType is deleted. So no validation happens for socialApp before saving (it assumes no validation needed since no change happened). But actually a change happened. But it doesn't get reflected.
If we recall appType by
SocialAppType *appType = [socialApp socialAppType];
appType is nil.
Weird, isn't it? We get nil for a non-optional attribute?
So you are in no trouble if you have set up the inverse relationship.
Otherwise you have to do force validation by writing the code as follows.
SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated
[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];
[socialApp setValue:nil forKey:#"socialAppType"]
BOOL saved = [managedObjectContext save:&error];
In practice, I haven't had any data loss due to not having an inverse - at least that I am aware of. A quick Google suggests you should use them:
An inverse relationship doesn't just
make things more tidy, it's actually
used by Core Data to maintain data
integrity.
-- Cocoa Dev Central
You should typically model
relationships in both directions, and
specify the inverse relationships
appropriately. Core Data uses this
information to ensure the consistency
of the object graph if a change is
made (see “Manipulating Relationships
and Object Graph Integrity”). For a
discussion of some of the reasons why
you might want to not model a
relationship in both directions, and
some of the problems that might arise
if you don’t, see “Unidirectional
Relationships.”
-- Core Data Programming Guide
I'll paraphrase the definitive answer I found in More iPhone 3 Development by Dave Mark and Jeff LeMarche.
Apple generally recommends that you always create and specify the inverse, even if you don't use the inverse relationship in your app. For this reason, it warns you when you fail to provide an inverse.
Relationships are not required to have an inverse, because there are a few scenarios in which the inverse relationship could hurt performance. For example, suppose the inverse relationship contains an extremely large number of objects. Removing the inverse requires iterating over the set that represents the inverse, weakening performance.
But unless you have a specific reason not to, model the inverse. It helps Core Data ensure data integrity. If you run into performance issues, it's relatively easy to remove the inverse relationship later.
There is at least one scenario where a good case can be made for a core data relationship without an inverse: when there is another core data relationship between the two objects already, which will handle maintaining the object graph.
For instance, a book contains many pages, while a page is in one book. This is a two-way many-to-one relationship. Deleting a page just nullifies the relationship, whereas deleting a book will also delete the page.
However, you may also wish to track the current page being read for each book. This could be done with a "currentPage" property on Page, but then you need other logic to ensure that only one page in the book is marked as the current page at any time. Instead, making a currentPage relationship from Book to a single page will ensure that there will always only be one current page marked, and furthermore that this page can be accessed easily with a reference to the book with simply book.currentPage.
What would the reciprocal relationship be in this case? Something largely nonsensical. "myBook" or similar could be added back in the other direction, but it contains only the information already contained in the "book" relationship for the page, and so creates its own risks. Perhaps in the future, the way you are using one of these relationships is changed, resulting in changes in your core data configuration. If page.myBook has been used in some places where page.book should have been used in the code, there could be problems. Another way to proactively avoid this would also be to not expose myBook in the NSManagedObject subclass that is used to access page. However, it can be argued that it is simpler to not model the inverse in the first place.
In the example outlined, the delete rule for the currentPage relationship should be set to "No Action" or "Cascade", since there is no reciprocal relationship to "Nullify". (Cascade implies you are ripping every page out of the book as you read it, but that might be true if you're particularly cold and need fuel.)
When it can be demonstrated that object graph integrity is not at risk, as in this example, and code complexity and maintainability is improved, it can be argued that a relationship without an inverse may be the correct decision.
An alternative solution, as discussed in the comments, is to create your own UUID property on the target (in the example here, every Page would have an id that is a UUID), store that as a property (currentPage just stores a UUID as an Attribute in Book, rather than being a relationship), and then write a method to fetch the Page with the matching UUID when needed. This is probably a better approach than using a relationship without an inverse, not the least because it avoids the warning messages discussed.
The better question is, "is there a reason not to have an inverse"? Core Data is really an object graph management framework, not a persistence framework. In other words, its job is to manage the relationships between objects in the object graph. Inverse relationships make this much easier. For that reason, Core Data expects inverse relationships and is written for that use case. Without them, you will have to manage the object graph consistency yourself. In particular, to-many relationships without an inverse relationship are very likely to be corrupted by Core Data unless you work very hard to keep things working. The cost in terms of disk size for the inverse relationships really is insignificant in comparison to the benefit it gains you.
While the docs don't seem to require an inverse, I just resolved a scenario that did in fact result in "data loss" by not having an inverse. I have a report object that has a to-many relationship on reportable objects. Without the inverse relationship, any changes to the to-many relationship were lost upon relaunch. After inspecting the Core Data debug it was apparent that even though I was saving the report object, the updates to the object graph (relationships) were never being made. I added an inverse, even though I don't use it, and voila, it works. So it might not say it's required but relationships without inverses can definitely have strange side effects.
Inverses are also used for Object Integrity (for other reasons, see the other answers):
The recommended approach is to model relationships in both directions
and specify the inverse relationships appropriately. Core Data uses
this information to ensure the consistency of the object graph if a
change is made
From: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html#//apple_ref/doc/uid/TP40001075-CH17-SW1
The provided link gives you ideas why you should have an inverse set. Without it, you can lose data/integrety. Also, the chance that you access an object which is nil is more likely.
There is no need for inverse relationship generally. But there are few quirks/bugs in Core data where you need an inverse relationship. There are cases where relationships/objects go missing , even though there is no error while saving the context, if there are missing inverse relationship. Check this example, which I created to demonstrate objects missing and how to workaround, while working with Core data