Object-Relational
Mapping
a subclass or superclass, and independent of the behavior
of the caller.
Change detection keeps track of changes made to
domain objects that are used in a database transaction so
that at the end of the transaction, changes are applied to
the database.
Uniquing is a property of database interaction in which
a single domain instance corresponds to a database
row, regardless of how the user acquired the object: via
querying the database, navigating a reference from one
instance to another, or finding a distinct domain instance
by providing its primary identity. Without uniquing,
changes made to one domain instance will not be seen by
other domain instances representing the same database
row; this might result in database corruption.
Database independence allows use of a common API and
domain model to operate with various databases without
changing the application view of the database.
The earliest—and still very popular—technologies for
accessing relational databases use APIs to transmit SQL
statements to the server and return the results of executing the statements back to the application. It is left up to
the application to use the results directly or to create data
structures that represent the query results, and to copy
the query results to these data structures.
Data structures that directly model query results cannot model relationships that exist in the database; therefore, associations among instances of the data structures
are poorly represented. Examples of this style of access
include ODBC (Open Database Connectivity) and JDBC
(Java Database Connectivity) interfaces. These interfaces
allow for limited separation of concerns, but most often
business logic is mixed with database programming. They
do not support information hiding, inheritance, change
detection, uniquing, or database independence.
More capable technologies provide methods in the
interface to copy the query results to user-specified data
structures. The user provides all of the SQL statements
annotated so they correspond to the data structures. The
SQL statements created by the user include all queries,
plus insert, update, and delete. These technologies handle
much of the error-prone and time-consuming jobs of
analyzing the results of queries but still leave many of
the difficult tasks to the user. One example of this style
of access is iBATIS, which supports information hiding
and a limited separation of concerns but not inheritance,
change detection, uniquing, or database independence.
With ORM, data stored in relational databases is represented to the application as objects in the native object
programming language. Programmers map domain object
model classes to relational tables and use an API implemented by a persistence provider to access the database.
Queries against the database are expressed in terms of the
domain object model. The provider generates SQL statements directly from the domain model. Martin Fowler
has called this approach DataMapper. 2
ORM techniques and products are available for many
object-oriented languages, including Java, C++, C#,
Python, Smalltalk, Ruby, and Groovy. The techniques and
programming paradigms for ORM apply to many of the
products that support these languages. (In this article,
examples are given in Java.)
ARCHITECTURE OF ORM
The application’s view of ORM consists of two major
parts: the persistence API and the domain classes. In Java,
the API is typically one of the Java Community Process
standards—Java Persistence API, Enterprise JavaBeans, or
Java Data Objects—or nonstandard yet popular APIs such
as TopLink or Hibernate.
An advantage of using a standard persistence API is
that it allows projects to make a late deployment decision
on both the database and the persistence provider. This
can be a significant factor in many projects where the
need for features that differentiate persistence providers is
not obvious at the beginning of the project.
The persistence API allows the application programmer to perform all of the standard CRUD (create, read,
update, delete) operations of the database. Since the
application programmer does not access the rows and
columns of the database directly, a shorthand notation
describes the behavior. For example, “make an instance
of a mapped domain persistent” is shorthand for “create
a row or rows in the database that correspond exactly
to the instance of the mapped domain class.” Likewise,
“delete an instance of a domain class” means “delete
the database row or rows that correspond exactly to the
instance of the domain class.”