Advertisment

Inheritance Mappings in Hibernate

author-image
PCQ Bureau
New Update

One of the key object/relational paradigm mismatch concerns is replicating

"IS-A" relationship (inheritance) from the domain model to a DB schema. For

example, in Java, we implement type inheritance using superclasses and

subclasses. However, SQL doesn't provide support for supertables and subtables.

Hibernate, an Open Source Object Relational Mapping (ORM) solution can bridge

this gap between the relation and the domain object world. This article

continues from the December 2007 issue where we explored the "Table per class

hierarchy" strategy. In this article, we'll examine yet another inheritance

mapping strategy provided by Hibernate-Table per subclass. Note that we'll

continue using the same MedTracker application for demonstration.

Advertisment

Direct Hit!

Applies To: Adv Java developers



USP: Map each class from the domain inheritance tree to a
separate database table



Primary Link:
www.hibernate.org/hib




docs/reference/en/html/inheritance.html


Keywords:
Hibernate Inheritance



Mappings

Table per sub-class approach



As the name suggests, in “table per sub-class” approach, there exists one

table per class in the underlying database. Note that there will be a table

created even for abstract classes and interfaces. The "table per subclass"

approach represents inheritance relationships as foreign key associations. Each

table corresponding to a subclass has a primary key association to the

superclass table. Besides the primary key association, the tables here contain

columns only for non-inherited properties of the class. This approach is quite

different from the "table per class hierarchy" approach, wherein, the DB schema

has one table which represents all properties in the inheritance tree, apart

from a discriminator column.

As an illustration, consider the following code snippet which walks through

with the mapping file used to implement table per subclass strategy (for

brevity, the entire code is not shown).

Advertisment

default-access="field">



















Advertisment


Advertisment




Advertisment
















Advertisment



















As shown in the preceding code snippet, 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. As shown,

the element is used to join a subclass table to the superclass

table. The element is used to refer to the primary key of the superclass

table. According to the Hibernate reference, it's used to define the foreign key

in the joined table, which references the primary key of the original table. The
complete source code is available on the CD.

The main benefit of this strategy is that the schema is normalized. Also,

note that unlike the "table per class hierarchy" strategy we don't require an

additional discriminator column. However, queries always require join across

tables which can reduce performance.

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;

and 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();


}



The output after executing the client application is shown in Listing 2 below

(for brevity, not all log messages are shown).

create table EMPLOYEE (PERSON_ID bigint not null,

POLICY_NO bigint, primary key (PERSON_ID))



create table PATIENT (PERSON_ID bigint not null, DIAGNOSIS varchar(255),
DATE_OF_ADMISSION datetime, primary key (PERSON_ID))



create table PERSON (PERSON_ID bigint not null auto_increment, F_NAME
varchar(255), L_NAME varchar(255), GENDER varchar(255), AGE integer, primary key

(PERSON_ID))



alter table EMPLOYEE add index FK75C8D6AEA857FAF4 (PERSON_ID), add constraint
FK75C8D6AEA857FAF4 foreign key (PERSON_ID) references PERSON (PERSON_ID)



alter table PATIENT add index FKFB9F76E5A857FAF4 (PERSON_ID), add constraint
FKFB9F76E5A857FAF4 foreign key (PERSON_ID) references PERSON (PERSON_ID)



schema export complete


Hibernate: insert into PERSON (F_NAME, L_NAME, GENDER, AGE) values (?, ?, ?, ?)


Hibernate: insert into EMPLOYEE (POLICY_NO, PERSON_ID) values (?, ?)





As discussed, Hibernate's hbm2ddl.auto DB schema generator tool will create

three tables, one for each class in the domain model. Furthermore, as shown

above, each subclass table has a primary key association to the superclass table

(PERSON).

Conclusion



Hibernate inheritance strategies bridge the gap between DBAs and Java

developers by providing an easy and seamless way of replicating Java "IS-A"

relationship to underlying database tables. JPA, an EJB 3.0 sub-specification

borrows these concepts from Hibernate to map entities to database tables.


Advertisment