Each kind of persistent objects (such as "Artist" or "Painting") is described in Cayenne by a single ObjEntity. The most common and useful scenario is mapping an ObjEntity to a "specialized" Java class, one class per entity. But there is an alternative - use a single generic persistent object class to map any entity.
|Generic DataObject hints|
|When to Use Generic Objects|
Generic objects are not type-safe and are not convenient for manual coding. Most applications should stick to concrete classes. Generic objects are useful in cases when all persistent properties are not fully known at compile time. It is also possible to use a hybrid approach when new persistent properties are added to the existing concrete class at runtime.
If you don't enter anything for Java Class of an ObjEntity, Cayenne assumes generic mapping and uses the following implicit rules to determine a class of a generic object. First it will check whether a DataMap "Custom Superclass" is set. If so, runtime uses this class to instantiate new objects. If not, org.apache.cayenne.CayenneDataObject is used.
CayenneModeler and Ant class generators skip ObjEntities that are mapped to CayenneDataObject explicitly or have no class mapping (i.e. implicitly mapped to a generic class).
One difference between using a specific class per entity and using generic objects is that a String entity name is used in places where you would normally use a Java class. The examples below demonstrate this:
Create a new object:
Create a new object when using a generic ObjectContext that does not define "newObject(String)" method. In this case we must set ObjectId explicitly - this will tell Cayenne what entity the generic object belongs to:
Determine object entity name:
Read a simple property value (attribute or relationship):
Read a "nested" property value spanning a chain of DataObjects:
Modify a property value: