Maybe you expect the UML-design sketch of an O/R access layer now. Sorry. Before we come to this we have to talk about design forces and requirements for an object/relational access layer. We follow the line that we will first explain what we need to build before we explain how you can build it. The latter will happen in the section on general architecture for o/r layers and also OODBMS.
The following set of forces that influence the design of an o/r access layer is adapted from Accessing Relational Databases [Kel+98a]. There are only a few more forces here than for pure relational access layers:
Check you do not build one of the above applications before you map objects to relations.
Given that you have to use a relational database and given that you want a fully object-oriented application kernel it is good to have a list of typical functionality for an object-oriented database. The Object-Oriented Database System Manifesto [Atk+89] (direct link) contains a very comprehensive list of the functionality you might want to provide (see Table 1) with your object/relational access layer.
OODBMS
Manifesto: Mandatory Features |
Object/Relational Access
Layers: Covered by |
(1) Complex Objects |
Your programming language for business objects (like C++, Smalltalk, Java, ...), your RDBMS plus an access layer. |
(2) Object Identity |
See Object Identity Pattern |
(3) Encapsulation |
Your programming language |
(4) Types and Classes |
Your programming language |
(5) Class or Type Hierarchies |
Your programming language plus patterns for Mapping Objects to Tables. |
(6) Overriding, overloading and late binding |
Your programming language |
OODBMS
Manifesto: Mandatory Features |
Object/Relational Access
Layers: Covered by |
(7) Computational Completeness |
Your programming language |
(8) Extensibility |
Your programming language plus patterns for Mapping Objects to Tables. |
(9) Persistence |
Whole access layer plus relational database (RDBMS). |
(10) Secondary storage management |
RDBMS |
(11) Concurrency |
RDBMS plus patterns for transaction control and locking strategies. |
(12) Recovery |
RDBMS |
(13) Ad Hoc Query Facility |
access layer on top of RDBMS |
Table 1: Core responsibilities of an Object-oriented Database Management System
Most of the functionality listed in Table 1 comes with your object-oriented programming language (like 1, 3, 4, 5, 6, 7, 8). The challenge is to make your object-oriented programming languages objects persistent, giving them the ability to survive the termination of the actual process and to be used again in other (also in parallel) processes.
Therefore the other requirements are typical requirements that you find for databases (like 9, 10, 11, 12,13). See any database book for an explanation, e.g. [Dat95].
The main pattern for object/relational access layers is Two Layer Persistency Subsystem. But at the top level you will find other patterns that are also concerned with coarse structure. Follow the hot spots on the Roadmap in order to find the right source..
Figure 4: Local Roadmap: Architecting an Object/Relational Access Layer
Problem
What is good way to structure an object-oriented database or an object/relational access layer?
Forces
Remember the above discussion on Separation of concerns versus cost: Database programming is complex, storage subsystems are complex but they are known abstractions. Object-oriented programming languages are also proven concepts. Both have enough complexity. Mapping one concept to the other and not dividing into further subsystems could easily sum up to a nightmare of complexity. The easiest way is to separate the concepts of object-orientation from those of database programming and to separate the object-oriented database aspects from the relational database aspects. You are then able to exploit well- known patterns for each of the problem domains. The cost of separated layers has to pay off with increased maintainability and easier performance tuning.
Application style is another force. You should be able to adapt you object persistence subsystem to the different application styles mentioned above. It makes a great difference, whether you intend to write a transaction oriented system or a system that can best be described with check in/check out persistence.
Finally the possible integration of legacy data sources will have its effects on you design.
Solution
Build your system as two subsystems that form a layered structure. The upper layer, called the object layer, encapsulates the concepts of object-orientation while the lower layer, called the storage manager, offers a high level interface on top of your physical storage devices or file system. A relational database in this context is just another physical storage device.
Structure
Figure 5: Two Layer Structure of a Persistency
Subsystem for
Object-Oriented Programming Languages (o-o programming languages)
Assign the following responsibilities from The Object-Oriented Database System Manifesto [Atk+89] to the layers.
The object layer encapsulates the concepts of object orientation. It has the following responsibilities: (1) Complex Objects, (2) Object Identity, (3) Encapsulation, (4) Types and Classes, (5) Class or Type Hierarchies, (6) Overriding, overloading and late binding, (7) Computational Completeness, (8) Extensibility, (13) Ad Hoc Query Facility. This is the object-oriented programming languages part of the requirements listed in Table 1.
The Storage Manager provides an interface to a Physical Storage Subsystem. It has the following responsibilities: (9) Persistence, (10) Secondary storage management, (11) Concurrency, (12) Recovery, (13) Ad Hoc Query Facility. This is the database part of the requirements listed in Table 1. The only exception is the "Ad Hoc Query Facility". The Ad Hoc Query Facility is a database concept that you wrap at the level of your object-oriented language in order to offer your user the equivalent of SQL. Therefore you have to deal with some form of Object SQL (also called Object Query Language (OQL) [ODMG93]) in both layers.
This discussion could lead to some form of abstract pattern. Whenever you have two paradigms that need to be mapped on one another, you can come up with an architecture that consists of two layers. These layers contain the respective abstractions of the two paradigms, and the upper layer (the paradigm you want to map onto another) needs some code to call the lower layer this code is mostly in the broker patterns (see Moving Attributes to and from the Tuple Layer)
Consequences
Manageability and complexity: This approach breaks the problem down into manageable parts by cutting it into two halves and one of these, the storage manager, is not a new problem but a kind of component with a long lasting design history.
Application Style: You can adapt your persistence subsystem to different application styles by plugging in different storage managers. The need to adapt to transactional legacy systems will influence your storage manager but not your object layer.
Variants
An object/relational access layer is a variant of an object-oriented database. An architectural sketch from POET makes this quite evident. POET is an object-oriented database that uses a relational database (plus an access layer) as its storage subsystem.
If you do not use an object-oriented database with a relational database as its storage manager you have to build an object/relational access layer. For the rest of the paper we will use the term tuple layer instead of storage subsystem as we use relational databases to store our objects.
Figure 6: Two Layer Structure for an Object/relational access Layer
Related Patterns
We have used the concepts of Layers [Bus+96] here. All the other patterns in this paper are further solutions to the problems of how to build such an access layer.
Known Uses
Most object-oriented databases and object/relational access layers are built this way. We have already cited POET [POE97] as an arbitrary example. TopLink is an example that uses the pattern in a object/relational access layer product [TOP97a,TOP97b]. There are many project solutions, that follow the same architecture [Bar+95, Hah+95, Kel+98b, Sta+97, Wal+95]. Another use of the architecture can be found in [Hei98]. Heinckiens distinguishes an object layer, a database layer and brokers between the two layers, which he calls Impedance Mismatch Resolvers.
-> on to the Object Layer
-> up to the Contents Page