Core Data: Abstract Entity in Fetch Request - objective-c

Suppose I have a Core Data model with an abstract entity called "Animal." Then, I have many other entities that inherit from this abstract entity: "Lion", "Dog", "Cat", etc. (I'm not developing a zoo program, but this analogy works well for the issue I'm explaining!)
What I want to know is: Can I fetch "all animals" at once by doing this:
NSFetchRequest *searchRequest = [[NSFetchRequest alloc] init];
[searchRequest setEntity:[NSEntityDescription entityForName:#"Animal" inManagedObjectContext:aContext]];
NSArray *matchedObjects = [aContext executeFetchRequest:searchRequest error:nil];
I understand there are methods on NSEntityDescription to determine whether an entity inherits from another. But is there a fast way to grab all entities that are of a particular (abstract) type --- in this case, "Animal"?
If the approach above is invalid, what is the most efficient way to go about this? Thanks!

You can definitely use that approach.
From Apple's Core Data Programming guide:
Entity inheritance works in a similar way to class inheritance; and is useful for the same reasons. If you have a number of entities that are similar, you can factor the common properties into a superentity, also known as a parent entity. Rather than specifying the same properties in several entities, you can define them in one entity, and the subentities inherit them. For example, you might define a Person entity with attributes firstName and lastName, and subentities Employee and Customer, which inherit those attributes.

I've done something similar, however that entity was not abstract. It was a standard entity (with no instances) and the other entities that I fetched were all derived from that entity. I haven't tried it with an abstract class, however, looking at the docs it appears that it might not be possible:
Core Data Programming Guide
Abstract Entities You can specify that
an entity is abstract—that is, that
you will not create any instances of
that entity. You typically make an
entity abstract if you have a number
of entities that all represent
specializations of (inherit from) a
common entity which should not itself
be instantiated. For example, in a
drawing application you might have a
Graphic entity that defines attributes
for x and y coordinates, color, and
drawing bounds. You never, though,
instantiate a Graphic. Concrete
sub-entities of Graphic might be
Circle, TextArea, and Line.
My suggestion would be to set things up with the abstract Animal entity and give it a shot. If it doesn't work then just make the Animal entity non-abstract (words are failing me, is that what we would call it? Perhaps 'concrete' is better?) and you should be fine. If anyone has done this with an abstract class I would to hear about it.

Yes, I believe you can fetch all the Animals at once.
From the Core Data Programming guide:
Entity Inheritance
If you specify a parent entity in Core Data as the
entity for a Core Data fetch request, the fetch returns matching
instances of the entity and subentities (see Fetching Objects). As a
corollary, if you specify a parent entity as the entity for a
controller that is backed by Core Data, it fetches matching instances
of the entity and any subentities. If you specify an abstract parent
entity, the Core Data backed controller fetches matching instances of
concrete subentities.

Related

Skip subentity of abstract entity and just implement subclasses programatically?

I have a core data abstract entity which is backed by a class that's subclassed for many concrete [sub]entities that I create and manipulate instances of. No attributes or relationships or properties are different in the subclasses. I'm just overriding method implementations. So other then setting the subclass and parent entity, the xcdatamodeld is empty for each subentity.
If there are no unique properties or relationships in the subentities in xcdatamodeld, and I'm creating quite a number of them, is there some code that I could create in the abstract superentity class to handle the core data subentity registration?
What I'm looking for is some reasonable code that lets me just create a .h/.m for each new subentity (which subclasses the abstract entity, which subclasses NSManagedObject), and skip seemingly duplicate and cluttering work in xcdatamodeld of +entity, edit name, add class, declare parent entity. Is this feasible and reasonable? Or do I go down a rabbit hole of arcane programmatic managedObjectModel editing outside of my class implementations?
[edit] To add background about why subclasses. One-- each subclass creates a different tree of child entities. Two-- each subclass assembles its data differently for passing to views. ie they all have the same string properties, but each subclass might present an attributedStringForTitle differently than the next.
Probably the closest you will get is by using mogenerator. You may be able to script changes to the data model, but unless you're going to create lots of classes then it likely won't save you time.

how to serialize polymorphic to-many Core Data relationship with RestKit?

I need to serialize a Core Data class (Questionnaire) which has a to-many relationship (questions) to an abstract entity (Question).
Question is the parent entity for a number of concrete subclasses (BooleanQuestion, ClosedQuestion…), each of which has an RKManagedObjectMapping.
How can I set up the Questionnaire mapping to serialize this polymorphic relationship?
If it was not polymorphic, I would do:
[questionnaireMapping mapRelationShip:#"questions" withMapping:[questionMapping inverseMapping]];
But I can't do that: questions will not be of any single class, so there isn't a single mapping to pass.
Moreover, Question being abstract, doesn't even have a mapping (though I could define one).
How can I handle that with RestKit version 0.10.3?
Note that I am very close to releasing my product, and I am really reluctant to migrate to RestKit 0.20 this late in my product cycle.
I guess I could aggregate all concrete Question subclasses into Question, making it concrete and monomorphic (and monolithic). That would be ugly (though I believe this is precisely what Core Data does with SQLite behind the scene).
Anything more elegant?
Thanks
JD
Upgrading to 0.20 wouldn't help anyway as I don't believe this situation is covered there either.
I would recommend you to implement a method (or just use KVC) on each of the classes in the hierarchy which returns a dictionary of the keys and values. This can be done efficiently using KVC -dictionaryWithValuesForKeys:. The list of keys should be the union of all keys for all classes. Now you can build an array of dictionaries which can be mapped. You would also need to implement KVC -valueForUndefinedKey: to prevent exceptions during this process.
Now, on your Questionnaire class you can implement a method to loop over the questions relation contents and build the list of dictionaries. Say the method was called encodedQuestions, your mapping would be something like:
[questionnaireMapping mapRelationShip:#"encodedQuestions" withMapping:questionDictMapping];
I haven't actually tried doing this so there is a question about the reflection RestKit uses on Core Data objects and how happy it will be taking your relation mapping.

Repository design for complex objects?

What is the best way to design repositories for complex objects, assuming use of an ORM such as NHibernate or Entity Framework?
I am creating an app using Entity Framework 4. The app uses complex objects--a Foo object contains a collection of Bar objects in a Foo.Bars property, and so on. In the past, I would have created a FooRepository, and then a BarRepository, and I would inject a reference to the BarRepository into the FooRepository constructor.
When a query is passed to the FooRepository, it would call on the BarRepository as needed to construct the Foo.Bars property for each Foo object. And when a Foo object is passed to the FooRepository for persistence, the repository would call the BarRepository to persist the objects in the Foo.Bars property.
My question is pretty simple: Is that a generally accepted way to set up the repositories? Is there a better approach? Thanks for your help.
In domain-driven design, there is the concept of a "root aggregate" object. The accepted answer to a related question has good information on what it is and how you would use it in your design. I don't know about the Entity Framework but NHibernate does not require the usage pattern you are describing. As long as all the nested objects and their relationships are properly mapped to tables, saving the aggregate root will also save all its child object. The exception is when a nested object has specific business logic that needs to performed as part of its access or persistence. In that case, you would need to pass the "child" repositories so you are not duplicating that business logic.
Repository pattern helps grouping of business transactions among related entities. Meaning if you have two domain objects foo and bar and have a common transactions like GetList(),Update() then a common repository like FoobarReporsitory can be created. You can even abstract that to an interface called IFoobarReporsitory to make application loosely coupled.

Core Data inheritance: Is it OK to do this?

Example: I have an Entity called Car which is abstract. Then there are two child entities Cabriolet and Pickup.
Now I have an Entity called Driver which has a Relationship called currentCar 1..1 to the Entity Car. So I can assign either a Cabriolet or a Pickup to any driver's currentCar property. Then I would need to introspect the object to find out at runtime if I have a Cabriolet or Pickup when I get the currentCar from the driver. Is this a valid design in Core Data?
I don't see why this wouldn't work on a technical level, but it does violates OOP polymorphism.
Why do you need to know if the type of car? Would you be able to define the methods on the abstract superclass (Car) and override them as appropriate in the the subclasses (Cabriolet and Pickup)? Could you refactor the car hierarchy so that the attributes of the subclasses become more general and move them to attributes of Car, thus removing the need for the subclasses?
I had trouble with NSFetchResultsController when fetching objects derived from a common superclass. (The returned objects can only be sorted/grouped by an attribute of the entity. The class type is not an attribute so cannot be used to sort/group the entities. My solution/hack was to a type attribute to the superclass - ugly, but it worked.)

What's the difference between entity and class?

Is entity an instance of class?
A class is a template for an object (among other things), and is a very general concept.
An entity has more semantic significance and is usually tied to a concept (possibly about a real object for example, an Employee or a Student or a Music Album) and is linked to business logic.
Entities are usually used to establish a mapping between an object and to a table in the database. Entities are also known as domain objects. Like I mentioned before, entities will be used in situations where there is business logic and as such it hold information about the system (or part of the system) that it is modeling.
To add one more point
Class is a syntactic i.e. A set or category of things having some property or attribute in common and differentiated from others by kind, type, or quality.
Entity is a semantic i.e. relating to meaning in language or logic. An entity is something that exists in itself, actually or potentially, concretely or abstractly, physically or not. It needs not be of material existence.
Object is a in-memory value referenced by identifier, it is an instance of a Class.
An entity usually refers to something, anything really, that has a unique and separate existence.
In software development this word is almost only used to denote that one instance is different from another instance and they are independent of each other.
A class, on the other hand, defines or contains the definition of an object. Once that object is constructed based on the definition, then you get your instance or object instance.
Short -- yes.
Entity is more a concept from real world.
Instance (alias is object) -- from programming world.
In programming world we also has an "entity" concept, but here it's more a child of an instance. So any entity is a child of instance. Also entity has it's links to other things but programming -- for example, as people said -- entity can have table in DB.
Instance can't have table in DB. As instance is always connected to class.
An object is an entity that has state, behavior, and identity. The structure and
behavior of similar objects are defined in their common class. The terms instance
and object are interchangeable.
From Grady Booch book.
So we could say, that entity, object and class instance are interchangeable.
Entities
An entity is a lightweight persistence domain object. Typically an entity represents a table in a relational database, and each entity instance corresponds to a row in that table. The primary programming artifact of an entity is the entity class, although entities can use helper classes.
The persistent state of an entity is represented either through persistent fields or persistent properties. These fields or properties use object/relational mapping annotations to map the entities and entity relationships to the relational data in the underlying data store.
Entity classes have a stereotype of entity. An entity class is essentially an object wrapper for a database table. The attributes of an entity are transformed to columns on the database table. Entities can have various data maintenance operations such as read, insert, modify, remove, readmulti (read multi reads multiple records from a table based on a partial key).
Entities can have attributes, operations, dependencies, inherits relations, and aggregations. A set of rules is associated with each of these constructs.
Entity class rules
Entities must have at least one attribute. The exception is if the entity is a subclass of another entity, in which case the entity must have no attributes. Entities are not allowed to aggregate other classes.
Entity attributes
Entity attributes correspond to columns with the same name on their associated database table.
Entity operations
Entity operations can be divided into two categories as determined by their stereotype: database and non-database operations.
Entity outputs
Entity classes are transformed into classes with operations and no attributes. The attributes from the entity in the input meta-model are transformed into one or more structs.
Entity class options
The options available for entity classes are entity class abstracts, allow optimistic locking, audit fields, enable validation, last updated field, No Generated SQL, and replace superclass.
Optimistic locking for concurrency control
Using optimistic locking for concurrency control means that more than one user can access a record at a time, but only one of those users can commit changes to that record.
Table-level auditing
Use the Database table-level auditing option to enable table-level auditing.
Exit points
An exit point is a callback function that you write. It is executed at a predefined strategic point by the server.
Entity inheritance
Input meta-model entity classes can subclass other entity classes.
Last updated field
The last updated field is a field that you can add to database tables to contain extra information about the modification time of each record for reporting purposes.
Also you can check this link and this link for more information!
I copy from this paper, "Entity based Programming Paradigm", Nimit Singhania. University of Pennsylvania:
An entity is an abstract unit that represents a group of
nodes or sub-entities. It uses the services provided by its
sub-entities and collaboration between these sub-entities to
achieve its required goals. It has its own identity and appears
as a single unit to the external world just as in real
life a team or an organization is a whole unit and not just a
collection of individuals. A distributed system is essentially
a hierarchy of entities where each entity has a specific role
and provides specific services [...]
[...]The entity abstraction is very similar to an object in object
oriented programming. The key difference between an object
and an entity is that an entity is an active and a live
unit while an object is passive. An entity consists of live subentities
interacting with each other to provide a service and
can possibly interact with the other entities. Whereas, an
object consists of only static fields and properties that can be
queried and manipulated by the external world. But, many
insights from object oriented programming can be carried
over to this programming paradigm. We can have classes
and types of entities, where a class might provide specific
services and functionality to the rest of the system. Also,
we could define abstract entities which implement the core
structure and some basic protocols for interaction between
nodes and these could be extended further to realize the actual
entities. Similarly, we could define interfaces that define
a set of services. These interfaces could be implemented by
multiple entities with different guarantees and based on the
requirements, one of them could be chosen by the programmer
to provide the required service.