|
Advertisement |
Object relational Mapping
Posted On August 23, 2010 by Sneha Latha filed under Miscellaneous
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:
- Data Definition Language (DDL): Provides ways to create and alter tables.
- Data Manipulation Language (DML): Provides ways to manipulate and retrieve data. It includes inserting, updating and deleting data.
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 |
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






Salim KS commented, on August 25, 2010 at 5:15 p.m.:
I need more articles on JAVA.