PATH  Documentation > WebObjects 4.5 > EOF Developer's Guide

Table of Contents Previous Section

Defining the Model

The work of writing enterprise objects typically begins in EOModeler. You make the following decisions for your enterprise object in EOModeler:

These issues are discussed in the following sections.

EOGenericRecord or Custom Class?

Enterprise Objects Framework provides a "default" enterprise object class, EOGenericRecord. An EOGenericRecord can take on values for any properties defined in your application's model (see the section "Accessing an Enterprise Object's Data" for more discussion of this), but implements no custom behavior. EOGenericRecord objects can hold simple values as well as refer to other enterprise objects through relationships defined in the model.

The criterion for deciding whether to make your enterprise objects custom classes or to simply use the EOGenericRecord class is behavior. One of the main reasons to use the Enterprise Objects Framework is to associate behavior with your persistent data. Behavior is implemented as methods that "do something," as opposed to merely returning the value for a property. Since the Framework itself handles most of the behavior related to persistent storage, you can focus on the behavior specific to your application.

Because the Customer class in the Rentals database has specialized behavior-for example, it rents units-it needs to be a custom class.

Which Attributes Should Be Class Properties?

By default, EOModeler marks all of the attributes read in from the database as class properties. When an attribute is marked as a class property, it means that the attribute will be included in your class definition when you generate source files for the class, and that it will be fetched and passed to your enterprise object when you create instances from the database.

The attributes you mark as class properties should only be ones whose values are meaningful in the object graph that's created when you fetch objects from the database. Attributes that are essentially database artifacts shouldn't be marked as class properties. For example:

What Data Types Should Your Properties Be?

When you create a new model, Enterprise Objects Framework maps external database data types to the following standard value classes:
Java Objective-C
String NSString
BigDecimal (java.math) NSDecimalNumber
Number NSNumber
NSGregorianDate NSCalendarDate
NSData NSData

Additionally, you can map external data types to custom value classes defined by your application. When you're working with custom data, you'll typically want to convert binary data into a meaningful form. However, since you define its form, you have to convert it yourself. The Framework allows you to define a custom class whose instances are initialized with binary or string data; this prevents your accessor methods from having to explicitly convert the data, and allows other objects to access your enterprise object's property in its intended form rather than as an NSData object. For more discussion of this subject, see the chapter "Advanced Enterprise Object Modeling".

Working with Numeric Values

There are basically two different choices for representing numeric values in your model:

Conversion of Numeric Values

When the Framework passes a Number value (NSNumber in Objective-C) to your object, the value can be converted to the corresponding scalar (numeric) type if your accessor method or instance variable requires it (for more information, see "Accessing an Enterprise Object's Data"). For example, suppose your enterprise object defines these accessor methods:

public void setAge(int age)
public int age

For the setAge method, the Number value for the "age" key is converted to an int and passed as age. Similarly, the return value of the age method is converted to an Number.

How Should Your Enterprise Object Manage Relationships with Other Objects?

In EOModeler you can specify relationships between entities. For example, in the Rentals database in the on-line examples, the Member entity can have several relationships to other entities, including:

You can use relationships to access data in the destination entity from the source entity.

When you include relationships as class properties, to-one relationships are represented as references in the object graph and to-many relationships are represented as NSArrays. You can see this more clearly if you look at the way Customer's to-one relationship to CreditCard and to-many relationship to Rental are represented as instance variables in the Customer class:

// Reference to a CreditCard object in the object graph
protected CreditCard creditCard;

// Array of Rental objects
protected NSMutableArray rentals;
For the most part, you access the data in other objects by using relationship properties to traverse the in-memory object graph in your running application. For example, the following statement uses Customer's creditCard relationship to access the authorizationDate property in the CreditCard object:

date = customer.creditCard().authorizationDate();
Likewise, the following statement uses the Customer's rentals relationship to return an NSArray containing a customer's Rental objects:

rentalArray = customer.rentals(); 

Referential Integrity

When your enterprise object has relationships with other objects, you can use EOModeler to define rules to govern those relationships. Each of the rules possible are described briefly in the following sections. For more information on how to set these options, see the book Enterprise Objects Framework Tools and Techniques.

Optionality

Optionality refers to whether a relationship is optional or mandatory. For example, you can require all departments to have a location (mandatory), but not require that every employee have a manager (optional).

Delete Rules

This refers to the rules that should be applied to an entity that's involved in a relationship when the source object is deleted. For example, you might have a department with multiple employees. When a user tries to delete the department, you can:

You can set a source object as owning its destination objects. When a source object owns its destination objects and you remove a destination object from the source object's relationship array, you're also deleting it from the database (alternatively, you can transfer it to a new owner). This is because ownership implies that the owned object can't exist without an owner-for example, line items can't exist outside of a purchase order. By contrast, you might have a department object that doesn't own its employee objects. If you remove an employee from a department's employees array, the employee continues to exist in the database, but its department variable is set to null (or nil in Objective-C). If you really intend to delete the employee from the database, you'd have to do it explicitly.

Propagates Primary Key

You can also specify in EOModeler that the primary key of the source entity should be propagated to newly inserted objects in the destination of the relationship. This is used for a to-one owning relationship, where the owned object has the same primary key as the source. For example, in the Movies database the TalentPhoto entity has the same primary key as the entity that owns it, Talent. In this scenario, if you create a new Talent object and the Talent doesn't already have a TalentPhoto, the Framework automatically creates a TalentPhoto object for you.

Mapping an Entity Across Multiple Tables

In certain special cases you may decide to use EOModeler to "flatten" attributes from one entity into another. In general you should only flatten attributes across one-to-one relationships (like Employee to Address) where the destination entity is never fetched directly. Otherwise, you run the risk that the values of flattened attributes can get out of sync with the most current view of data in your application.

Some examples of good uses of flattened attributes are as follows:

When you use flattened attributes, you don't need to include the relationship as a class property-there's no need to since the data it would be used to access is already included in the source entity.

For more discussion of this topic, see the book Enterprise Objects Framework Tools and Techniques.

What about Inheritance?

You can use the Advanced Entity Inspector in EOModeler to specify an entity's parent entity. For example, the Customer entity is a parent to both Member and Guest in the RentalsInheritance model. For more discussion of the different approaches you can use for inheritance, see the chapter "Advanced Enterprise Object Modeling".

Table of Contents Next Section