Advertisement

Object relational Mapping

HTML clipboard

ORM sands for Object relational Mapping. ORM is an attempt to map the notion of object and relational world, so that they can talk to each other smoothly and transparently. In this article, we will look into the ORM concepts in the context of Java, however the concepts are equally applicable to any other OO language.

Any non trivial application has a database behind it and Java applications are no exceptions. In fact if we look closely into any application, one will realize that the application gets more or less modeled around the data model. In database technology, relational databases are the clear winners. Other database technologies has come and gone. Relational concept of data management was first introduced by E.F. Codd in 1970. An analogy for relational model can be drawn with spreadsheets. Each sheet represents a table and the columns in the sheet represent the table attributes. Each instance of data is represented by the rows. The data in different sheets are connected with each other by referring to the data point using the sheet number, column number and row number. This is what is called as foreign key relationship in database technology. In fact, most of the GUI interfaces to database show the data in a spreadsheet format.

To interact with the database, Structured Query Language (SQL) has emerged as the standard way. The SQL standards are controlled by ANSI. However there are still proprietary variations to it. SQL provides two types of mechanism:

To interact with the database, the application has to issue SQL to the database. How to issue SQL is proprietary to each database. They have their own API's exposed for this and the API's might be written in different languages. For example a database written in C language might expose C based API's. Considering that the data independence is considered a virtue for any application, it would be a lot of work for an application developer to understand the interfaces for each of the database and implement it. To solve this kind of problem, Java has come up with JDBC api's.

JDBC is the most popular way of connecting to databases in Java. It's an interface based API where the implementation for each database is provided by the drivers for particular database. Though JDBC is very popular, it is inherently relational in nature. The basic problem is the mismatch in conceptual level between relational technology and Object Oriented Technology. Java being a pure Object Oriented Language, this mismatch is important to deal with. This mismatch is also known as Object relational mismatch. Let's understand the kind of mismatch that arises between Object and relational world. In this article, we will not delve into the strategies of ORM framework to solve these issues.

Inheritance

Java supports inheritance. For example we might have User class from which Student and Teacher class is derived.

User class

public class User{
private Long id;
private String Name;

//Setters and getters
}
Student
public class Student extends User{
private Double percentage;

//Setter and Getter
}

Teacher
public class Teacher extends User{
private Integer exprienceYears;

//Setters and Getters
}

Now think for a moment, how you are going to map these classes to the table structure. 

First let's understand the mapping part of the class structure. We have an inheritance tree and we want to map it to a data model. Two mapping possibilities are:

· Single Table per inheritance structure: This strategy is about putting a single Table which has all the data related to User, Student and Teacher. The type of data is differentiated with a discriminator column. The table structure would look like

User

User_Id
Name
Percentage
Exprience_Years
Discriminator

This mapping is best in performance but it's not possible to enforce null constraints.

·        Single Table per class: In the mapping, a single table exists against each class. The table structure looks as follows:

User

Student

Teacher

User_Id

Name

 

Student_Id

User_Id (foreign key)

Percentage

Teacher_Id

User_Id (foreign key)

Exprience_Years

 

This mapping has the advantage in terms of ability to define null constraints. However performance wise its not as good as the first mapping.

 

There are mappings which lie between the two extremes, where number of tables is more than one but less than the number of classes. 

Also with this comes the mismatch in terms of polymorphism. A reference of User type can refer to an object of Student or Teacher. Also a list might contain a mix of Teacher, Student and User objects. How you build those list by querying database. The ORM framework has to somehow differentiate that the data is belonging to User or Student or Teacher. 

Granularity
The granularity problem comes, when the number of classes mapping to number of tables in the database do not match. For example let's say we have the User class which has an Address object

public class User{
private Long id;
private String Name;
private Address address;

//Setters and getters
}

Address class
public class Address{
private String city;
private String country;

//Setters and getters

The table structure for the user is 

User

User_Id

Name

City

Country

There is one table but the data is sitting in two objects. The same problem can come the other way round also, where you have two tables and one class containing all the data points. An ORM framework has to care of this mismatch, in terms of different number of tables mapped to different number of classes.

Identity and Equality
The notion of identity is driven by primary key in relational model. Given a primary key you will always retrieve the same data. Also it does not matter, how many clients are retrieving the same data. With right isolation level all will see the same data values. In Java, the situation becomes more complex. The same data row might be represented by more objects in Java layer. For example a User data in database with primary key 1 might have more than one object in different thread. The question comes which is the object, having the right data. Also if all thread try to save the same object, than who wins? Similar problem arises related to equality. In Java the default is reference equality. If the references are pointing to the same object, than they are equal. The corollary is that if there are two objects representing the same data row, they will come out as different. To solve this we have to give implementation to the equals() method, but it's not always trivial. An ORM solution has to provide provisions to maintain the correct notion of equality and identity. To solve this, ORM framework generally expect the right implementation of equals() and hashcode(). Also the identity is mapped to an attribute in the class.

Association
In Java the relationship is done by association. For example User has a reference of address. However in Tables, the relationship is done with foreign key association. Java has also the notion of directionality. For example you can access address form User but not the other way round. To build the relationship from both side, you have to put the reference on both the sides.

User

public class User{
private Address address;

//Setters and Getters
}

Address

public class Address{
private User user;

//setters and getters
}

However there is no notion of directionality in the relational world. The foreign key relationship can be done at any one end and the relationship is build. With SQL you can navigate from any end. For example the table structure of User and Address are as follows:

User

Address

User_Id

Name

Address_Id (Fk)

Address_Id

City

Country

An ORM solution has to deal with these associations while setting and getting the data from the database.

Type Systems
Object Oriented and relational world has different type systems. For example in relational world string can be constrained on the size. However on the Java side you can point the reference of String to any size based on memory allocated. Also date and times are handled differently in Java and relational world. For example in databases, there is a distinction between date, time and timestamp. Time stamp contains both date and time. In Java, the date is a long value which contains both date and time. So when you fetch the date or time from relational world how you map it to a Java data type of Date or Calendar.

Databases are Different
There are so many popular databases in the market. In spite of SQL being a standard, there are still variations in the SQL support in each database, and there are many vendor extensions and individual flavors in each database. Though this is not really an ORM issue but it is important from the perspective of database portability, if you are looking for it. Ensuing database portability using JDBC is usually a hurricane task if you wish to use the individual flavors of database for performance or other reasons. ORM frameworks attempt to handle most of the important databases transparently. Also they do have extension mechanisms if you wish to support another database. 

ORM frameworks adopt different strategies to solve these kinds of mismatches. ORM frameworks strive to preserver the notion of object world concepts and shield the developers from relational world by taking care of mappings. This should not be taken as an excuse to not to learn relational concepts. In fact on the other way round, to be a good user of ORM frameworks, one should understand how the mapping works and the implications of it. The most important issue in using ORM frameworks is performance. The fundamental reason of performance issues are about not understanding the relational concepts and how ORM frameworks deal with them.

-------------------------------------------------------------------------------------------------------------------
Lalit Bhatt is a consultant and trainer in Software application development using Java technologies. He can be reached at 
http://www.lalitbhatt.com or at lalit.bhatt@gmail.com








Added on August 23, 2010 Comment

Comments

#1

Salim KS commented, on August 25, 2010 at 5:15 p.m.:

I need more articles on JAVA.

Post a comment