The EOModel

Version 15.1 by Pascal Robert on 2012/03/10 08:32

Information

Work in progress! Right now, most of the text is coming from Apple's documentation. We need to change that, and add Wonder and WOLips specific information.

The EOModel

While it may seem obvious, data modeling is perhaps the most important phase of WebObjects application development. Data models form the foundation of your business logic and business logic forms the core of your application. Good business logic is essential to building effective applications, so it follows that good data models are essential to the success of the applications you build. Most importantly, data modeling plays a crucial role in object-relational mapping, the process in which database records are transposed into Java objects.

Using data models to develop data-driven applications provides you a unique advantage: applications are isolated from the idiosyncrasies of the data sources they access. This separation of an application's business logic from database logic allows you to change the database an application accesses without needing to change the application.

Also, WebObjects provides a rapid development environment that enables the creation of full-featured Web and desktop applications based on data models. So if you build well-designed data models, WebObjects gives you usable applications for free without any code.

Whenever possible, data modeling should occur in the earliest phases of application design and development. In data-driven applications, data modeling almost always influences an application's goals. That is, you cannot define an application's goals outside of the context of the application's data models.

Data models in Enterprise Objects reflect the earliest decisions about what data users see and how they are allowed to interact with data. This is because an important part of data modeling is deciding which entities and attributes are visible to clients and editable by clients. So by including data modeling as an early part of the design process, you can simplify future implementation details.

WebObjects provides you with a great tool for object-relational mapping called EOModeler. It allows you to
■ build data models either from scratch or by analyzing preexisting data sources using reverse engineering
■ add and customize entities (tables) and attributes (columns)
■ form relationships between entities
■ form relationships across multiple models
■ generate SQL from a model to create or update a data-source schema based on the model
■ generate Java classes from a model in which you can add custom business logic
■ use stored procedures within data models
■ graphically build fetch specifications for retrieving data
■ flatten attributes and relationships
■ define derived attributes
■ build database queries in raw SQL

In an Entity-Relationship model, distinguishable things are known as entities, each entity is defined by its component attributes, and the affiliations, or relationships between entities, are identified (together, attributes and relationships are known as properties). From these three simple modeling objects--entities, attributes, and relationships--arbitrarily complex systems can be modeled.

Entities

In a relational database data model, entities represent tables and an entity's attributes represent columns.

Each row in the table can be thought of as an instance of an entity. So, a customer record is called an instance of the Customer entity. Each instance of an entity typically maps to one object, but more complex mappings are possible.

Entities and attributes in data models derive their names based on the database elements they represent. A CUSTOMER table in a database, for example, would likely map to an entity named "Customer," though this is not strictly required. In your application, you refer to the CUSTOMER table not by its database name but by using its entity name, Customer.

Entity characteristics

Class Name
The name of the class that corresponds to the entity. If you don't define a custom enterprise object class for an entity, the class name defaults to EOGenericRecord. You should use a fully qualified name but this isn't strictly required.

Client-Side Class Name
The name of the class that corresponds to the entity in the client side of a three-tier WebObjects Java Client application. If you don't define a client-side class, Enterprise Objects looks for a class in the client with the same name as the server-side enterprise object class. If no such class exists on the client, it uses EOGenericRecord. You should use a fully qualified name but this isn't strictly required.

External Query
Any valid SQL statement that you want executed when unqualified fetches are performed on the entity.

Name
The name your application uses for the entity. By default, EOModeler supplies a name based on the name of the corresponding table in the data source.

Open Entity
Adds a column with an icon which you can double-click to display an entity's attributes.

Parent
Specifies an entity's parent when using inheritance.

Qualifier
Specifies a restricting qualifier that is added to every fetch specification performed on the entity. Used when modeling inheritance hierarchies.

Read Only
Specifies if the entity is read-only.

Table
The name of the table in the data source that corresponds to the entity

Advanced Entity Inspector

Batch Faulting Size lets you specify the number of faults that should be triggered when you first access an object of this type that is the destination of a to-many relationship. By providing a number in this field, you specify that number of faults of the same entity should be fetched from the data source along with the first fault. This improves performance by minimizing round trips to the data source.

External Query lets you specify any SQL statement to execute when Enterprise Objects performs an unqualified fetch on the entity. The columns selected by this SQL statement must be in alphabetical order by internal name and must match in number and type with the class properties specified for the entity.

Qualifier is used to specify a restricting qualifier. A restricting qualifier maps an entity to a subset of rows in a table. When you add a restricting qualifier to an entity, it invokes a fetch for that entity to retrieve objects only of the type specified by the restricting qualifier. See "Implementing Single-Table Mapping in a Model" (page 77) for more information on restricting qualifiers.

Parent is used to specify a parent entity for the current entity. This field is used to model inheritance. See "Modeling Inheritance" (page 67) for more details on this topic.

Read Only specifies whether the data that's represented by the entity can be altered by your application. This does not lock objects at the database level but rather works at a higher level (in the com.webobjects.eoaccess.EODatabaseContext object) so that if you try to save changes to data that's marked as read only, Enterprise Objects refuses the save and throws an exception.

Cache in Memory specifies that when one record in a table is fetched, the entire table is fetched into memory. Caching an entity's objects allows Enterprise Objects to evaluate queries in memory, thereby avoiding round trips to the data source. This is most useful for read-only entities where there is no danger of the cached data getting out of sync with the data in the data source.

Abstract lets you specify whether the entity is abstract. An abstract entity is one for which no objects are ever instantiated. For example, in the Real Estate database, the User entity is abstract and is never instantiated, whereas entities that inherit from it, such as Agent and Customer, are concrete classes that are instantiated. Like the Parent field, this option is used when modeling inheritance.

Attributes

Contained within an entity is a list of attributes of the thing that's being modeled. The Customer entity could contain attributes such as a customer's first name, last name, phone number, and so on.

Entities can also have derived attributes, which do not directly correspond to any of the columns in the database table to which the entity maps. These attributes are usually computed from one or more attributes in the entity. For example, a derived attribute could represent the total amount of money spent by a customer by adding the amounts of all a customer's purchases together.

Value Types

Value Type
When you choose a value class for a particular attribute, you sometimes do not provide Enterprise Objects with all the information the JDBC adaptor needs to negotiate with the data source.

For example, when you specify Number as the value class for a particular attribute, you are telling Enterprise Objects to use java.lang.Number, which is an abstract class. This is where the value type characteristic steps in. It specifies the exact class an attribute should map to.
The possible value types for numeric attributes are as follows(note case):

■ b---java.lang.Byte
■ s---java.lang.Short
■ i---java.lang.Integer
■ l---java.lang.Long
■ f---java.lang.Float
■ d---java.lang.Double
■ B---java.math.BigDecimal
■ c---java.lang.Boolean

Prototypes

To make creating models easier, EOModeler supports prototype attributes. These are special attributes from which other attributes derive their settings. A prototype can specify any of the characteristics you normally define for an attribute. When you create an attribute, you can associate it with one of these prototypes, and the attribute's characteristics are then set from the prototype definition.

For example, you can create a prototype attribute called lastModified whose value class is Date, whose external type is datetime, and which corresponds to a column named LASTMODIFIED. Then, when you create other entities, you can create an attribute and associate it with this prototype and the prototype's values are copied in to the new attribute. You can then change any values in or add values to the new attribute. Any value that is inherited from the prototype that you don't override uses the value defined in the prototype..

Creating Prototype Attributes
The prototypes you can assign to attributes can come from two places:
1. An entity named EOAdaptorNamePrototypes, where AdaptorName is the name of the adaptor for your model. WebObjects 5.2 includes an adaptor for JDBC data sources and an adaptor for JNDI data sources. So you can create a prototype entity called either EOJDBCPrototypes or EOJNDIPrototypes, depending on the adaptor you use.
2. An entity named EOPrototypes.

To create a prototype attribute, first create a prototype entity--an entity named either EOAdaptorNamePrototypes or EOPrototypes--and add an attribute to it. Figure 3-3 shows an attribute in a prototype entity. It shows all the values that prototype attributes can define: column name, value class, external type, and value type.

To assign a prototype attribute to an attribute, reveal the Prototype column in table mode, and select a prototype attribute from the pop-up menu. The prototype attributes that appear in the pop-up list in the Prototype column include prototype attributes defined in any entity in any model in the application's model group, which includes the current model.

Relationships

Every relationship has a cardinality. The cardinality defines how many destination records can potentially resolve the relationship. In relational database systems, there are generally two cardinalities:

■ to-one relationship---for each source record, there is exactly one corresponding destination record
■ to-many relationship---for each source record, there may be zero, one, or more corresponding destination
records

An employeeDepartment relationship is an example of a to-one relationship: An employee can be associated with only one department in a company. An Employee entity might also be associated with a Project entity. In this case, there would be a to-many relationship from Employee to Project called projects since an Employee can have many projects.

The construction of a relationship requires that you designate at least one attribute in each entity as a relationship key.

There are some general guidelines when choosing which attributes to use as relationship keys. In to-one relationships, the destination key must be a primary key in the destination entity. In to-many relationships, the destination key is usually a foreign key in the destination entity (which is most often a copy of the source entity's primary key). The source key or foreign key should emulate the destination key in that the data types must be the same and the names should be similar.

When you use relationship keys to express an affiliation between two entities, keep in mind these general rules:
■ For to-one relationships, the source attribute is a foreign key in the source entity while the destination key is the primary key of the destination entity.
■ For to-many relationships, the source attribute is the primary key in the source entity (but it can also be a foreign key in the source entity) while the destination key is a foreign key of the destination entity.

If you have consistency checking enabled in EOModeler, it warns you if any to-one relationships in your model have destination keys that are not primary keys.

If the data source on which your model is based includes foreign key definitions, these definitions are automatically expressed in your model when you create a model from an existing data source with the New Model Wizard. But if you are creating the schema within EOModeler, you need to define relationships in the model editor.

To 1 Relations

To Many Relations

Many to Many Join Tables

Flattened Relations

A flattened attribute is a special kind of attribute that you effectively add from one entity to another by traversing a relationship. When you form a to-one relationship between two entities (such as Person and PersonPhoto), you can add attributes from the destination table to the source table. For example, you can add a personPhoto attribute to the Person entity. This is called "flattening" an attribute and is equivalent to creating a joined column---it allows you to create objects that extend across tables.

Flattening attributes is just another way to conceptually "add" an attribute from one entity to another. A generally better approach is to traverse the object graph directly through relationships. Enterprise Objects makes this easy by supporting the notion of key paths.
The difference between flattening attributes and traversing the object graph (either programmatically or by using key paths) is that the values of flattened attributes are tied to the database rather than the object graph. If an enterprise object in the object graph changes, a flattened attribute can quickly get out of sync.

For example, suppose you flatten a departmentName attribute into an Employee object. If a user then changes an employee's department reference to a different department or changes the name of the department itself, the flattened attribute won't reflect the change until the changes in the object graph are committed to the database and the data is refetched (this is because flattened attributes are derived attributes---see "Definition (Derived Attributes)" (page 38) for more details). However, if you're using key paths in this scenario, users see changes to data as soon as they happen in the object graph. This ensures that your application's view of the data remains internally consistent.

Therefore, you should use flattened attributes only in the following cases:

■ If you want to combine multiple tables joined by a one-to-one relationship to form a logical unit. For example, you might have employee data that's spread across multiple tables such as ADDRESS, BENEFITS, and so on. If you have no need to access these tables individually (that is, if you'd never need to create an Address object since the address data is always subsumed in the Employee object), then it makes sense to flatten attributes from those entities into the Employee entity.
■ If your application is read-only.
■ If you're using vertical inheritance mapping. See "Vertical Mapping" (page 69).

Reflexive Relationships

A unique kind of relationship is the reflexive relationship---a relationship that shares the same source and destination entity. Reflexive relationships are important when modeling data in which an instance of an entity points to another instance of the same entity.

For example, to show who a given person reports to, you could create a separate manager entity. It would be easier, however, to just create a reflexive relationship. The managerID attribute is the relationship's source key whereas employeeID is the relationship's destination key. Where a person's managerID is the employeeID of another employee object, the first employee reports to the second. If an employee doesn't have a manager, the value for the managerID attribute is null in that employee's record.

Reflexive relationships can represent arbitrarily deep recursions. So, in the model above, a person can report to another person who reports to yet another person, and so on. This could go on until a person's managerID attribute is null, which denotes that person reports to no one.

Owns Destination and Propagate Primary Key

The Owns Destination option lets you specify whether the relationship's source owns its destination objects. When a source object owns its destination object, for example, as when an Agent object owns its Customer objects, when a destination object (Customer) is removed from the relationship, it is also removed from the data source. Ownership implies that an owned object cannot exist without its owner.

The Propagate Primary Key option lets you specify that the primary key of the source entity should be propagated to newly inserted objects in the destination of the relationship. That is, when inserting objects that are the destination of the relationship, this option suppresses primary key generation for the destination entity and instead uses the source object's primary key as the primary key for the newly inserted destination object.

Advanced

Optionality

The Optionality section lets you specify whether a relationship is optional or mandatory. For example, you could require that all Document objects have a related Writer object but not require that all Document objects have a related Illustrator object. When you attempt to save an object that has a mandatory relationship that is not set (so the relationship is null), Enterprise Objects refuses the save and displays an error message stating that the object being saved has a mandatory relationship that must be set.

Delete Rule

The options in the Delete Rule section specify what to do when the source object of a relationship is deleted. There are four options:
Nullify disassociates all destination objects from the source object by removing references to them. So, when an Agent object is deleted, its related Customer objects are not deleted but the Customer objects' references to Agent are nullified (the entry in the join table is set to null).
Cascade deletes all objects that are the destination of a relationship whose source is deleted. So, when an Agent object is deleted, all of its related Customer objects are also deleted.
Deny refuses the deletion if a source object has any destination objects. So, if an Agent object has any Customer objects, deleting the Agent object is denied. In order for the deletion of the Agent object to succeed, its destination objects (Customer objects) must either be deleted or changed to something other than destination objects of the Agent object.
No Action deletes the destination object but does not remove any back references to the source object. So, if a Customer object is deleted, its reference to its Agent object is not removed. Using this option may result in dangling references in the data source.

Tips

The following tips are useful to keep in mind as you add relationships to your model:

The relationships you define in a model must reflect corresponding implementations in the data source, as well as the features supported by the adaptor your model uses. Enterprise Objects doesn't know, for example, if your adaptor supports left outer joins, so you need to be careful with regard to the characteristics you set for relationships.

Relationships can be compound, meaning that they can consist of multiple pairs of connected attributes. You can specify additional pairs of attributes only in the Relationship Inspector. Simply select a second source attribute and a second destination attribute and click Connect a second time.

A to-one relationship from one foreign key to a primary key must always have exactly one row in the destination entity---if this isn't guaranteed to be the case, use a to-many relationship. This rule doesn't apply to a foreign key to primary key relationship where a null value for the foreign key in the source row indicates that no row exists in the destination.

To-one relationships must join on the complete primary key of the destination entity.

Using Multiple Models

Relationships Across Models

The entities in one model can have relationships to the entities in another model. You can form such relationships even if the models map to different databases and different database servers.

When you add a model to a project, it becomes part of a model group. Every Enterprise Objects application includes a default model group, even if the project contains only one model. Each model you add to a project automatically becomes part of the project's model group. The only regulation between multiple models in a model group is that entity names must be unique.

Fetch Specs in Model

After you create and configure entities in EOModeler, you can also use it to build queries on those entities called fetch specifications. A fetch specification (a com.webobjects.eocontrol.EOFetchSpecification object) is the object Enterprise Objects uses to get data from a data source.

Each fetch specification can contain a qualifier, which fetches only those rows that meet the criteria in the qualifier. A fetch specification allows you to specify a sort ordering to sort the rows of data returned. A fetch specification can also have other characteristics, as discussed in this chapter.

Fetch specifications you build in EOModeler are referred to as named fetch specifications. To use a named fetch specification requires that you get hold of the model object in which the fetch specification exists. The code in Listing 7-1 retrieves a fetch specification called "MyFetch" in an entity named "Listing" by looking for it in all the models in the application's default model group.

If you define a qualifier like this:

(askingPrice < $askingPrice) and (bedrooms = $bedrooms) and (bathrooms = $bathrooms)

then the qualifier variables are replaced by 500000 (askingPrice), 4 (bedrooms), and 3 (bathrooms).


EOModelGroup modelGroup = EOModelGroup.defaultGroup();
EOFetchSpecification fs = modelGroup.fetchSpecificationNamed("MyFetch", "Listing");
fs = fs.fetchSpecificationWithQualifierBindings(dictionary);
NSMutableDictionary dictionary = new NSMutableDictionary();
dictionary.takeValueForKey("500000", "askingPrice");
dictionary.takeValueForKey("4", "bedrooms");
dictionary.takeValueForKey("3", "bathrooms");

Stored procedures

You can set up an EOModel so that Enterprise Objects automatically invokes a stored procedure for these operations on an entity:

Insert to insert a new object into an entity
Delete to delete an object from an entity
Fetch All to fetch all objects in an entity
Fetch w/ PK to fetch the object in an entity with a particular primary key
Get PK to generate a new primary key for an entity

The stored procedures you enter in the Stored Procedure Inspector must correspond to a stored procedure in the model. If you created the model from an existing data source and chose the Ask About Stored Procedures option in the wizard, stored procedures are already added to the model. If this is not the case, however, you can add stored procedures to the model using the Add Stored Procedure command from the Property menu.

Finally, some stored procedures take arguments that you can also define in EOModeler. To do this, select a stored procedure in the tree view, which displays its arguments in the table. You can add arguments to a stored procedure by choosing Add Argument from the Property menu. Figure 5-7 shows arguments in a stored procedure.

In order for Enterprise Objects to automatically invoke a stored procedure for these operations, you must adhere to the requirements for each type of operation.

For each of the operations, if the stored procedure associated with an operation returns a value, Enterprise Objects ignores the return value.

For Fetch All operations, the stored procedure must not take any arguments and it should return a result set for all the objects in the corresponding entity. The rows in the result set must contain values for all the columns Enterprise Objects would fetch if it were not using the stored procedure, and it must return them in alphabetical order.

That is, the stored procedure should return values for primary keys, foreign keys used in class property joins, class properties, and attributes used for locking. These values must be returned in alphabetical order with regard to the attributes with which they are associated. For example, consider a Listing entity that has the attributes listingID, bedrooms, and sellingPrice. A stored procedure that fetches all the Listing objects should return the value for a listing's number of bedrooms, then its listingID, and then its selling price.

For Fetch w/ PK operations, the stored procedure must take an "in" argument for each of the entity's primary key attributes (most entities have a single primary key attribute). The argument names must match the names of the entity's primary key attributes. For example, a Listing entity has a single primary key attribute named listingID, so the stored procedures argument as defined in the model must also be listingID.

A Fetch w/ PK operation stored procedure should return a result set containing the row that matches the primary key passed in by the argument. The row must be in the same form as rows returned by the Fetch All operation.

For Insert operations, the stored procedure must take an "in" argument for each of the corresponding entity's attributes. The argument names must match the names of the corresponding EOAttribute objects.

For Delete operations, the stored procedure must take an "in" argument for each of the entity's primary key attributes. The argument names must match the names of the primary key attributes as in a Fetch w/ PK operation stored procedure.

For Get PK operations, the stored procedure must take an "out" argument for each of the entity's primary key attributes. The argument names must match the names of the primary key attributes as in a Fetch w/ PK operation stored procedure.

Insert, Delete, and Get PK operations should not return a result set.

EO Inheritance

One of the issues that may arise in designing your enterprise objects--whether you're creating a schema from scratch or working with an existing database schema--is the modeling of inheritance relationships.

In object-oriented programming, it's natural to think of data in terms of inheritance. A Customer object, for example, naturally inherits certain characteristics from a Person object, such as name, address, and phone number. In inheritance hierarchies, the parent object or superclass is usually rather generic so that less generic subclasses of a related type can easily be added. So, in addition to the Customer object, a Client object also naturally derives from a Person object.

While this kind of thinking is inherent in object-oriented design, relational databases have no explicit support for inheritance. However, using Enterprise Objects, you can build data models that reflect object hierarchies. That is, you can design database tables to support inheritance by also designing enterprise objects that map to multiple tables or particular views of a database table.

Using inheritance adds another level of complexity to your data model, data source, and thus to your application. While it has its advantages, you should use it only if you really need to. This section provides information that will help you make that decision.

Suppose you're designing an application that includes Employee and Customer objects. Employees and customers share certain characteristics such as name and address, but they also have specialized characteristics. For example, an employee has a salary and a manager whereas a customer has account information and a sales contact.

Based on these data requirements, you might design a class hierarchy that has a Person superclass and Employee and Customer subclasses. As subclasses of Person, Employee and Customer inherit Person's attributes (name and address), but they also implement attributes and behaviors that are specific to their classes, as illustrated in Figure 7-1.

In object-oriented programming, when a subclass inherits from a superclass, the instantiation of the subclass implies that all the superclass' data is available for use by the subclass. When you instantiate objects of a subclass from database data, all the database tables that contain the data held in each class (whether subclass or superclass) must be accessed so that the data can be retrieved and put in the appropriate enterprise objects.

Vertical Mapping

In this approach, each class is associated with a separate table. There is a Person table, an Employee table, and a Customer table. Each table contains only the attributes defined by that class.

This method of storage directly reflects the class hierarchy. If an object of the Employee class is retrieved, data for the Employee's Person attributes must be fetched along with Employee data. The relationship between Employee and Person is resolved through a join to give Employee access to its Person data. This is also the case for Customer. Vertical mapping requires a restricting qualifier if you want to fetch records from a parent entity (Person in this example).

Advantages of Vertical Mapping

With vertical mapping, a subclass can be added at any time without modifying the Person table. Existing subclasses can also be modified without affecting the other classes in the inheritance hierarchy. The primary virtue of this approach is its clean, "normalized" design.

Disadvantages of Vertical Mapping

Vertical mapping is the least efficient of all the approaches. Every layer of the class hierarchy requires a join table to resolve the relationships. For example, if you want to perform a deep fetch from Person, three fetches are performed: a fetch from Employee (with a join to Person), a fetch from Customer (with a join to Person), and a fetch from Person to retrieve all the Person attributes. If Person is an abstract superclass for which no objects are ever instantiated, the last fetch is not performed.

Horizontal Mapping

In this approach, you have separate tables for Employee and Customer that each contain columns for Person. The Employee and Customer tables contain not only their own attributes, but all of the Person attributes as well. If instances of Person exist that are not classified as Employees or as Customers, a third table would be required. In other words, with horizontal mapping, every concrete class has a self-contained database table that includes all of the attributes necessary to instantiate objects of the class.

This mapping technique entails the same fetching pattern as vertical mapping except that no joins are performed. Horizontal mapping does not require restricting qualifiers.

Advantages of Horizontal Mapping

Similar to vertical mapping, a subclass can be added at any time without modifying other tables. Existing subclasses can also be modified without affecting the other classes in the class hierarchy.

This approach works well for deep class hierarchies as long as the fetch occurs against the leaves of the class hierarchy (Employee and Customer) rather than against the root (Person). In the case of a deep fetch, horizontal mapping is more efficient than vertical mapping since no joins are performed. It's the most efficient mapping approach if you fetch instances of only one leaf subclass at a time.

Disadvantages of Horizontal Mapping

Problems may occur when attributes need to be added to the Person superclass. The number of tables that need to be altered is equal to the number of subclasses---the more subclasses you have, the more effort is required to maintain the superclass.

If, for example, you need to add an attribute called middleName to the Person class, you then need to alter its subclasses, Employee and Customer. So if you have deep inheritance hierarchies or many subclasses, this can be tedious. However, if table maintenance happens far less often than fetches, this might be a viable approach for your application.

Single-Table Mapping

With single-table mapping, you put all of the data in one table that contains all superclass and subclass attributes. Each row contains all of the columns for the superclass as well as for all of the subclasses. The attributes that don't apply for each object have null values. You fetch an Employee or Customer by using a query that returns just objects of the specified type (the table includes a type column to distinguish records of one type from the other).

Unlike vertical mapping, you don't need to flatten any of Person's attributes into Employee and Customer since these entities already have all of Person's attributes. Each subentity maps to the same table and contains attributes only for the properties that are relevant for that class.

When multiple entities are mapped to a single database table, you must set a restricting qualifier on each entity to distinguish its rows from the rows of other entities. A restricting qualifier maps an entity to a subset of rows in a table. This means that this qualifier is always used when fetches are performed on the entity, as well as any other qualifiers used during the fetch.

Advantages of Single-Table Mapping

This approach is faster than the other two methods for deep fetches. Unlike vertical or horizontal mapping, you can retrieve superclass objects with a single fetch, without performing joins. Adding a subclass or modifying the superclass requires changes to just one table.

Disadvantages of Single-Table Mapping

Single-table mapping results in tables that have columns for all of the attributes of each entity in the inheritance hierarchy. It also results in many null row values. While these aren't really disadvantages, they may conflict with some database design philosophies.

Using Inheritance in Entity Modeler

To use Inheritance in your model, you first need to create your base entity. When done, right-click on the entity and select Subclass. A dialog will appear and will ask you to specify which kind of Inheritance you want to use, which entity is the parent and the name of the new (child) entity. When selecting Vertical or Single-Table Inheritance, you can also specify the qualifier (type = XX) in that dialog (you can do that part later too).

EOGenerator

Handling Blob Data

Connection Dictionary

Runtime Selection of the Connection Dictionary and Prototypes

Debugging JDBC Connections and Jdbc2info