While JDBC is the underlying API beneath (nearly) all database connections in Java, most modern applications now use what are known as Object-Relational Mapping frameworks (ORMs). The most famous of these being the underlying Java Persistence API (JPA) and Hibernate.
What is an Object-Relational Mapper (ORM)
An Object Relational Mapping framework, or ORM, seeks to tackle the structural mismatch between object models (OOP) and relational models (relational databases).
For instance, relational databases have a tabular (spreadsheet-like) architecture that outlines a collection of tables that use primary and foreign keys to relate to one another. How would you model database tables that properly represent complex Java objects that are composed of several sub-objects, have parent classes, and so forth? Well, this is the problem that ORMs tackle and why they are so frequently used. However, there's only so much that they can do because of what is known as object-relational impedance mismatch.
What is Object-Relational Impedance Mismatch
The Object-Relational Impedance Mismatch refers to the challenge arising from the inherent mismatch between the tabular structure of relational databases and the interconnected graph representation of data in object-oriented languages, leading to difficulties in seamlessly integrating these two models.
Object-Relational Impedance Mismatch Challenges
The five primary challenges presented by the Object-Relational Impedance Mismatch are granularity, subtypes, identity, associations, and data navigation.
1. Granularity
There are times when the number of classes in an object model exceeds the number of tables in the database, or vice versa, resulting in the object model being more or less granular than the relational model.
For example, consider a Java object model for a Payment that includes properties like product, amount, and date, as well as a Customer object containing properties such as name, emailAddress, phoneNumber and so on. In most cases, the corresponding relational database would have two separate tables for Payment and Customer linked through foreign keys. This results in a scenario where a single Java object corresponds to two relational database tables. This is the granularity problem.
2. Subtypes (inheritance)
Inheritance, a fundamental concept in object-oriented programming (as discussed in what is OOP), lacks a direct counterpart in relational databases.
Take, for instance, an application where users may be either a Student or a Teacher. Since both the Student and Teacher classes share common information as individuals, they could both extend a common Person class. However, relational databases do not provide a direct equivalent to inheritance. This is the inheritance problem.
3. Identity
In OOP, objects have inherent unique identities (i.e., b==c), along with equality checks (a.equals(b)). Relational databases, however, rely on primary keys for identity. And these primary keys need to be manually defined and managed. This is the identity problem.
4. Associations
In OOP, associations are expressed as unidirectional references, unlike the bidirectional relationships facilitated by foreign keys in relational databases. Achieving bidirectionality in Java requires defining the association twice.
Conversely, relational databases lack a mechanism to mirror the multiplicity of a relationship observed in the object model. For instance, if a Payment class exists, a nearly infinite number of instances of this class can be created in OOP, a functionality not replicable in RDBMS. This is the association problem.
5. Data navigation
Navigating through the properties of an object in OOP is straightforward, while in relational databases, it necessitates intricate queries such as joins to retrieve the desired information.
For instance, in the Payment class, accessing the Customer information directly could involve methods like payment.getCustomer().getEmail() in OOP. Conversely, in a relational database, a JOIN operation between the two tables is required. For instance:
SELECT email FROM Customer c
JOIN Payment p
ON p.customer_id = c.id
WHERE p.id = 1
Next Steps with ORMs
This course will not dive any further into the use of ORMs. You will dig into ORMs in great detail in the Advanced Java & Spring course.
Summary: Java Hibernate ORM
- Hibernate and Java Persistence API (JPA) are two commonly used ORMs
- An ORM is an Object-Relational Mapping framework
- ORMs facilitate integrating OOP Java applications with relational tables
- The term "Object-Relational Impedance Mismatch" is used to describe the inherent challenges of integrating OOP applications with relational databases.
What are the Five Object-Relational Impedance Mismatch
- Granularity
- Subtypes (inheritance)
- Identity
- Associations
- Data navigation