The API includes methods to make instances of a
mapped domain class persistent, to retrieve an instance
of a domain class by its primary identity, to find all
instances of domain class and subclasses by a query
expressed in terms of the domain class values, and to
delete an instance of a domain class from the database. Updates are done in the context of a transaction,
by retrieving an instance of a domain class and using
domain methods to modify values of the instance.
The domain classes that represent the application’s
view of the data stored in the relational database are typically either written by hand or generated from a database
schema using a tool. Typically declarative, the mapping
relates the domain object model to the relational schema
model and is defined before the application runs. Since
the domain classes need not contain specific persistence
behavior, the classes are often referred to as POJOs (plain
old Java objects).
The absence of persistence code allows operation of
the persistent classes independent of the persistence
aspect. Much of the behavior of the domain classes can
thus be tested without access to the database or to the
persistence environment. This style of programming
encourages separation of concerns and encapsulation.
Many tables map directly to domain classes, such as
Employee, Department, Customer, Order, LineItem,
Contract, Claim, Product, and so forth. Rows of these tables
are mapped to instances of the domain classes. Columns
of the tables are mapped to fields of the domain classes.
The so-called impedance mismatch between object and
database schema has generated much discussion, for good
reason. There are “deceptive similarities” between the two
technologies, according to Scott Ambler. 3 Lack of understanding the difference between the technologies can lead
to bad design choices and project failure.
The data model in object languages such as Java is
not exactly the same as in relational databases, so special
care must be taken to prevent problems from arising. For
example, the maximum lengths of character columns
must be specified in the relational schema, but Java
Strings are essentially unbounded.
Floating-point numbers may cause problems, too. Java
implements IEEE floating-point numbers; relational databases often have a different representation. The effect is
that not all values for floating-point numbers in Java can
be stored in the database, and vice versa.
Even fixed-precision decimal numbers may pose problems when mapped to relational schema. Java supports
fixed-precision decimal numbers that are self-describ-ing—that is, each value has a specific precision (number
of digits) and scale (number of digits to the right of the
decimal point). In the database, however, all numbers in
the same column have the same precision and scale.
Mapping between the application domain classes and
database schema is, by design, not isomorphic. On the
domain model side, certain aspects of the object model
are not mapped to the database, including behavior of
the classes and class variables. On the relational database
side, not all of the tables and columns in every schema
in the database are represented in the domain model,
nor are stored procedures. Additionally, domain models
might have several valid mappings.
Representing a database schema with a domain object
model is usually straightforward, especially if the schema
is well normalized. With an entity-relationship model
of the schema, each entity is mapped to a domain class.
Each simple relationship, implemented as a foreign key
in the schema, is mapped to a field of a reference type on
one side and a field of a multivalued type on the other.
Many complex constructs in the entity-relationship
model can be nicely mapped to object-model constructs.
For example, a join table in which the columns are
foreign keys to two different tables can be mapped to two
classes in which each class contains a field, the type of
which is a set of objects of the other class type.
On the other hand, storing an arbitrary domain object
model in a relational database can be challenging. Models
that represent relationships using abstract classes, deep
-firstName : String
-lastName : String
-middleName : String
-employeeId : integer
-hireDate : date
-weeklySalary : BigDecimal
-hourlyWage : BigDecimal