Inheritance mapping and support for polymorphic queries was a crucial feature missing in the traditional EJB 2.1 Entity Beans model. Hibernate, an Open Source object-relational mapping and persistence framework provides three strategies for entity inheritance. In the first of the series of two articles, we explore a simple inheritance mapping strategy used in Hibernate ORM.
|
Table per class hierarchy
As the name suggests, in 'Table per class hierarchy' approach, there exists only a single table in the database which represents each class in the hierarchy. To demonstrate different mapping strategies in Hibernate, we'll use the MedTracker app. We shall see how Hibernate can be used to map the 'IS-A' association to a single database table.
The root of the inheritance hierarchy is defined by the Person class. We'll define a class called Patient and have it extend the Person base class and define an Employee class that extends the Patient class. Employees will be treated with a special discount when they are admitted.
This is by far the most simple strategy to implement. The persistence engine does not have to do any complex joins, unions, or sub selects when loading the entity or when traversing a polymorphic relationship, because all data is stored in one table. As an illustration, consider the following code snippet taken from the mapping file to implement table per class hierarchy strategy.
As shown in this code, Hibernate uses the direct field access strategy mechanism. This means that you don't have to get into the mess of providing a getter/setter for every persistent property in the entity class. Hibernate can directly access private fields using the Reflection API. The single table per class hierarchy mapping requires an additional discriminator column. This column identifies the type of entity being stored in a particular row of the database table.
The single database table which Hibernate will create on the fly is named PERSON. The
Hibernate's hbm2ddl.auto DB schema generator tool will create only a single table in the database called PERSON. This single DB table contains all persistent properties from every class in the inheritance tree |
Client application
The client code is simple. We'll use a static singleton to startup Hibernate. The startup includes building a global SessionFactory object. A SessionFactory can open up new Sessions. A Session represents a single-threaded unit of work, while the SessionFactory is a thread-safe global object, instantiated once.
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person p=new Employee("Satish","Sharma","Male",26,"Common Cold",new java.util.Date(),new Long(1));
session.save(p);
session.getTransaction().
commit();
}
Conclusion
The single table per class hierarchy scales better than the other two strategies that we'll discuss in the next issue. However, there's one big limitation of this mapping strategy- columns declared by the subclasses may not have NOT NULL constraints. In the next article, we'll explore the remaining two inheritance mapping strategies-table per subclass and table per concrete class.