Object/Relational Impedance Mismatch

Shashi Bhushan
booleanbhushan
Published in
6 min readAug 21, 2021

This blog explain the problems about the mismatch in the object model and the relational model, formally called Object/Relational Impedance mismatch. This article is aimed towards beginner to intermediate app developers with some familiarity with relational databases. Although I use some Java terminologies, it’s not a pre-requisite to understand the content presented here.

Entity

Let’s briefly understand about entities. An Entity is a domain class that can be persisted in the database. Technically, It should be a public class with a no-arg constructor. Also, it’s not recommended to add final modifier with class as it hinders ORMs like hibernate to apply Proxy pattern for performance reasons.

Entities can be

  • Primitive data types
  • Serializable data types
  • Enums
  • Collections

The mismatch

In the object domain model, the entities have their own network of interconnected objects. These objects reference one another and thus, form a graph like structure in memory.

In database model, SQL operations such as joins always result in a tabular representation of the resulting data. It’s called transitive closure: the result of an operation on relations is always a relation. The schemas for entities in database model is tabular in nature. By database model, I specifically mean relational model. This does not apply for say, graph models.

The entities written in an Object Oriented style are mapped to database tabular style in order to persist them in the database. This presents a set of conceptual problems that are called Object/Relational impedance mismatch. The Slash(/) is sometimes used to emphasize on the two different domain models here.

The mismatch can be divided into few subproblems

1. Granularity Problem

Granularity is the extent to which a system is composed of smaller components. It is the relative size of the types you are working with.

Classes in object model does not have a stipulation i.e. One class can hold references of several classes and so on. Thus, Classes are composed of other classes.

In Database model, only two levels of granularity is possible, Tables and Columns. The columns can have data types but their type won’t be other tables, since sub-typing is not supported by relational database model.

As an example, consider a Ticket booking system. Here, the entity Cinema will have an Address. Naturally, there might be other entities (such as User) who can have an Address. Thus, it makes sense to have a separate class for Address and have an association from Cinema to Address.

Schema of Cinema in Object Model

This same schema does not apply for relational model, simply because we can have an addresses table but can’t have a type called Address in cinemas table. (database table names should always be plural). Thus, we have a problem of Granularity. The Cinema class in object model is at a higher granularity than the database model’s cinemas table.

2. Inheritance Problem

Another feature that object oriented paradigm supports is Type Inheritance. A User can be an abstract class and could have different child classes such as Customer and Administrator, both defining a user of the Ticket booking system but with different roles and privileges. This also adds polymorphic behaviour for the object instances.

sub-typing in object model

In database model, since a Table is not a type (you can’t have a data type called Table, isn’t it) hence super and sub-typing does not apply in the model.

3. Identity Problem

Relational model has exactly one notion of equality, by the primary key. If you are given data for two rows and you are to check if they represent the same row in database, you would check if they have same primary key or not.

In relational model, we add surrogate keys (the ID column) to uniquely identify a row. A surrogate key is a primary key column with no meaning to the user. Hence, a User might have a unique email but we don’t use that as primary key to allow users to be able to change their email in future and still be identified by the same row in database.

In object model however, there’s Object Identity (a == b) when two references point to the same object in memory and there’s Object equality (a.equals(b)) where objects may be pointing to different instances in memory but are same from logical point of view.

Neither of the two ways that object model uses to define equality is connected to the way it’s defined in relational model. We don’t use a surrogate key in object model. We normally use all the field values to check equality in object model.

4. Association Problem

Association means how the relationships between our entities are mapped and handled.

In object model, association represents the connection between classes using object references. The object references are directional and it’s always from one class to another. If Cinema class has Address reference, it does not mean i could go from Address to Cinema as well. For that, I need to have a Cinema reference in Address class.

Also, navigation means iterating over these references in the network of inter-connected objects. Additionally, a one-to-many relation from an Entity to another is defined by specialized collections like Set or List. I say one-to-many since many-to-many would mean both sides have a Set<Entity> defining one-to-many relation from it’s end. There’s no many-to-many in database sense here.

In relational model, an association is defined by using a foreign key. The foreign key also maintains the integrity of the association as well. You can’t have a value for foreign key that does not exist in the referred table. There’s no equivalent in the object model for this integrity check.

Foreign keys are also one-to-many or one-to-one (with a unique constraint on foreign key column) like object model, but they are non-directional and does not support navigation the way it’s done in object model. You create arbitrary relations with joins to navigate the data. many-to-many relations are supported by using a link table.

5. Data Navigation Problem

In object model, we walk to object network to reach from one association to another using the references/pointers between instances. So, cinema.getAddress().getCity() would give me City for a particular Cinema entity instance.

In databases however, there’s no way to navigate per se. If you want a city for a particular Cinema entity, you would do

select addresses.city from addresses inner join cinemas on addresses.cinema_id = cinemas.id where cinemas.id = ?;

Hence, you need to know that addresses has cinema_id, create an arbitrary relation by joining the two tables and then fetch a particular row using a where clause.

This is fundamentally different way of getting the desired data than object model. There’s no .getAddress() or .getCity() here.

Possible Solutions

The responsibility of database is to act as a persistence layer. These problems occur because we are trying to convert an object model’s entity into a database model’s entity. So, it becomes an application programmer’s responsibility to resolve these problems.

This is where we can leverage an ORM. It simplifies object/relational mapping and persistence from a Java application to a relational database, using the metadata described with the class. There might be other solutions as well (like SQLJ) that currently exist for this.

Let me know if you have any questions on the topic. Thanks for taking the time to read this.

--

--