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.)
Related
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.
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.
In my model all the derived classes have the same ** persistent** attributes and methods as the base abstract class. There are some class specific attributes which aren't persisted and methods have different implementation.
Right now I have about 4 inheriting classes, and I will add more in the future. The nature of the application is that such classes may be added for different uses, so its impossible to know them in advance. The only given is that they will all share the same methods and persistent attributes. The is one column which will be used as discriminator.
I am struggling with strategy. Obviously I don't want to write a ClassMap for each derived class. In fact I's like the persistence layer to be completely ignorant of these derived classes. I am thinking of having the derived classes be able to be created off the base class and to return a base class.
I don't suppose I have any better option?
Your approach is flawed in that the persistence layer can not be ignorant about the subclasses, because it needs to know what the class is when loading/storing.
What you can do is use a convention-based mapping instead of an explicit one (Fluent has Automapping, and ConfORM is convention/override based only), so you don't have to write every classmap.
In ConfORM, it's as easy as saying, for example, orm.TablePerClass<TheBaseClass>(), then mapper.CompileMappingFor(TheBaseClassAndAllItsSubclasses), and you'll get the mappings without any additional effort.
I saw in some NHibernate examples that an abstract base entity class is used, which has overridden Equals , GetHashCode , to handle transient entities , proxy object (in lazy loading scenario .. I guess) .
Is it really necessary to implement such an abstract base entity class to derive all my entities ?
Not necessary at all. It just makes things easier because you can put things like the Id on it. As well common functionality like you previously mentioned like Equals/GetHashCode.
Yeah, the base class itself is not required,but overriding Equals and GetHashcode is something you'll want to do on all your entities, so the base class makes thAt a lot less repetetive
In my experience, having a base class that exposes an Id property is really useful to be able to create generic repository methods that take advantage of that, or for automatic mapping conventions.
Overriding Equals, however, is another story.
Doing so forces loading of uninitialized proxies when you compare them (for example, by calling Distinct on a sequence). For that reason, it's better done only for class hierarchies of seldom-changing entities that are likely to be cached.
Overridding Equals is definetely required if you want to do lazy loading.
This is because NHibernate relies on the Equals method to determine equality. The default is reference equality.
When NHibernate implements lazy loading, it uses proxy objects, which are subclasses of the real entity class, with every member overridden to enable lazy loading.
Hence for your application to recognise that a proxy object is the same as the object it is meant to be the real instance - it shouldn't be aware of the proxy object at all.
So you must override the Equals operator to intelligently recognise equality (after checking reference equality ... etc) that objects are equal if their IDs are equal.
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.