Sunday, November 17, 2024
Google search engine
HomeLanguagesJavaHibernate – Table Per Subclass using Annotation

Hibernate – Table Per Subclass using Annotation

Hibernate is an open-source, non-invasive, lightweight java ORM(Object-relational mapping) framework that is used to develop persistence logic that is independent of Database software. An ORM(Object-relational mapping) framework simplifies data creation, data manipulation, and data access.  It is a programming technique that maps the object to the data stored in the database. It internally uses the JDBC API to interact with the database.

Inheritance in Hibernate

Hibernate can store the inherited properties of an object along with its new properties in its database when an object is saved in the database. In Hibernate, inheritance between POJO classes is applied when multiple POJO classes of a module contain some common properties. In a real-time application, POJO classes of Hibernate are designed based on database table design.

If more than one POJO class has some common properties then those common properties are separated into a POJO class called the base class and the properties which are un-common are stored in the derived class. This is the concept of Hibernate Inheritance mechanism. Hibernate is capable of storing the data of a class hierarchy of an application into either one table of the database or multiple tables of the database based on database design.

Hibernate Inheritance Mapping

Object-oriented can model both “is a” and “has a” relationship. The relational model supports only “has a relationship” between two entities. Hibernate helps in mapping such Objects with relational tables. There are three inheritance mapping strategies defined in the Hibernate.

  • Table Per Hierarchy
  • Table Per Concrete class
  • Table Per Subclass

Table per Subclass

In a table per subclass strategy (Using XML file)

  1. For each class of the hierarchy there exist a separate table in the database.
  2. Tables are created according to persistent classes but they are treated using primary and foreign keys so that there will not be any duplicate column in the relation.
  3. While creating the database table foreign key relationship is required between the parent table and child table.
  4. To pass information to the Hibernate that apply table per subclass mapping, we have to configure <joined-subclass> tag under <class> tag of hbm.xml file
  5. The discriminator column is optional

In a table per subclass strategy (Using annotations) 

  1. The discriminator is optional so we can avoid discriminator-related annotations.
  2. We need a separate table for the base class and for each derived class.
  3. To get a relation between the base class table and the derived class table we use a foreign key column in the derived class table
  4. Foreign key column in the derived class table can also be used as a primary key column for that derived class table to inform the Hibernate that a column of the table is acting as both primary key and foreign key. We use @PrimaryKeyColumn annotation for that purpose.

Important Annotations

Annotation 1: @Inheritance: This annotation 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. If this annotation is not specified or if no inheritance type is specified for an entity class hierarchy, the SINGLE_TABLE mapping strategy is used.

Syntax: @Inheritance

@Entity
@Table("name = students")
@Inheritance(strategy = InheritanceType.JOINED)

// Class 
public class Student {

    // Insert code here
}

Annotation 2: @PrimaryKeyJoinColumn

This annotation specifies a primary key column that is used as a foreign key to join to another table. It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass. It is used within a SecondaryTable annotation to join a secondary table to a primary table and it may be used in one-to-one mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity. If PrimaryKeyJoinColumn is not specified for a subclass in the JOINED mapping strategy, the foreign key column is assumed to have the same name as the primary key columns of the primary table of the superclass.

Syntax: @PrimaryKeyJoinColumn

@Entity
@Table("name = students")
@PrimaryKeyJoinColumn (name = "sid")

// Class
public class Student {
    // Insert code here
}

Annotation 3: @InheritanceType

This annotation defines inheritance strategy options. JOINED is a strategy in which fields that are specific to a subclass are mapped to a separate table than the fields that are common to the parent class, and a join is performed to instantiate the subclass.

Implementation: 

Table per subclass class using Annotation where In this example, we will be creating three persistence classes and provide the mapping of these classes in the student.hbm.xml file.

We will be creating different files that are listed as follows: 

  1. Employee.java
  2.  A class extending above Employee.java class 
  3. Dependency XML file
  4. Configuration XML file

A: Employee Class 

Java




// Java Program to Illustrate Implementation of
// Employee Class
 
package com.exploit.org;
 
// Importing required classes
import javax.persistence.*;
 
// Annotations
@Entity
@Table(name = "employee")
@Inheritance(strategy = InheritanceType.JOINED)
 
// Class
public class Employee {
 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
 
    @Column(name = "ID")
    private String id;
 
    @Column(name = "Name") private String name;
}


B: File: R_Employee.java, which is implementing above class “Employee”

Example:

Java




// Java Program to Illustrate Implementation of
// R_Employee Class
 
package com.exploit.org;
 
// Importing required classes
import javax.persistence.*;
 
// Annotations
@Entity
@Table(name = "r_employee")
@PrimaryKeyJoinColumn(name = "ID")
 
// Class
// Extending Employee class
public class R_Employee extends Employee {
 
    @Column(name = "salary") private double salary;
    @Column(name = "bonus") private double bonus;
}


C: File: C_Employee.java, which is implementing above class “Employee”

Java




// Java Program to Illustrate Implementation of
// C_Employee Class
 
package com.exploit.org;
 
// Importing required classes
import javax.persistence.*;
 
// Annotations
@Entity
@Table(name = "c_employee")
@PrimaryKeyJoinColumn(name = "ID")
 
// Class
// Extending Employee class
public class C_Employee extends Employee {
 
    @Column(name = "pay") private double pay;
    @Column(name = "contract") private String contract;
}


D: File: pom.xml 

Example:

XML




<dependency
       <groupId>org.hibernate</groupId
       <artifactId>hibernate-core</artifactId
       <version>5.3.1.Final</version
</dependency
 
<dependency
       <groupId>com.oracle</groupId
       <artifactId>ojdbc14</artifactId
      <version>10.2.0.4.0</version
 
</dependency>


Add the above following dependencies given below in the pom.xml file.

Later, create a hibernate.cgf.xml configuration file and add the entries of mapping resources.

Example:

XML




<mapping class="com.exploit.org.Employee"/> 
<mapping class="com.exploit.org.C_Employee"/> 
<mapping class="com.exploit.org.R_Employee"/>


RELATED ARTICLES

Most Popular

Recent Comments