Introduction to Inheritance in Hibernate

Java is an object oriented language. It is possible to implement Inheritance in Java. Inheritance is one of the most visible facets of Object-relational mismatch. Object oriented systems can model both “is a” and “has a” relationship. Relational model supports only “has a” relationship between two entities. Hibernate can help you map such Objects with relational tables. But you need to choose certain mapping strategy based on your needs.

One Table Per Class Hierarchy example

Suppose we have a class Person with subclass Employee. The properties of each class are:
* class Person
– firstname
– lastname

* class Employee
– joining_date
– department_name
In One Table per Class Hierarchy scheme, we store all the class hierarchy in a single SQL table. A discriminator is a key to uniquely identify the base type of the class hierarchy.
Following are the advantages and disadvantages of One Table per Class Hierarchy scheme.
Advantage
This hierarchy offers the best performance even for in the deep hierarchy since single select may suffice.
Disadvantage
Changes to members of the hierarchy require column to be altered, added or removed from the table.

Create Database Table to persist Class Hierarchy

CREATE TABLE `person` (
    `person_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
    `firstname` VARCHAR(50) NULL DEFAULT NULL,
    `lastname` VARCHAR(50) NULL DEFAULT NULL,
    `joining_date` DATE NULL DEFAULT NULL,
    `department_name` VARCHAR(50) NULL DEFAULT NULL,
    `discriminator` VARCHAR(20) NOT NULL,
    PRIMARY KEY (`person_id`)

The PERSON table will store both Employee and Person objects.

Following is the example where we map Employee and Person entity classes using JPA Annotations.
File: Person.java

package taher.javahunter.hibernate;
 
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
 
 
@Entity
@Table(name = "PERSON")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="discriminator",
    discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue(value="P")
public class Person {
 
    @Id
    @GeneratedValue
    @Column(name = "PERSON_ID")
    private Long personId;
     
    @Column(name = "FIRSTNAME")
    private String firstname;
     
    @Column(name = "LASTNAME")
    private String lastname;
     
    // Constructors and Getter/Setter methods, 
}

The Person class is the root of hierarchy. Hence we have used some annotations to make it as the root.
@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.
@DiscriminatorColumn – Is used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies. The strategy and the discriminator column are only specified in the root of an entity class hierarchy or sub hierarchy in which a different inheritance strategy is applied
If the @DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to “DTYPE” and the discriminator type to DiscriminatorType.STRING.
@DiscriminatorValue – Is used to specify the value of the discriminator column for entities of the given type. The DiscriminatorValue annotation can only be specified on a concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.
The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if not defaulted, should be specified for each entity class in the hierarchy.
File: Employee.java

package taher.javahunter.hibernate;
 
import java.util.Date;
 
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;
 
@Entity
@Table(name="PERSON")
@DiscriminatorValue("E")
public class Employee extends Person {
 
    @Column(name="joining_date")
    private Date joiningDate;
     
    @Column(name="department_name")
    private String departmentName;
 
    // Constructors and Getter/Setter methods, 
}

Employee class is child of Person class. Thus while specifying the mappings, we used @DiscriminatorValue to specify discriminator value. In our case “E” will be persisted in discriminator column.

Output :

Hibernate: insert into EMPLOYEE (FIRSTNAME, LASTNAME, discriminator) values (?, ?, ‘P’)
Hibernate: insert into EMPLOYEE (FIRSTNAME, LASTNAME, department_name, joining_date, discriminator) values (?, ?, ?, ?, ‘E’)

Advertisements
This entry was posted in Hibernate and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s