Tuesday, 30 July 2013

Hibernate Inheritance Joined Strategy Example

In this post , we will learn to implement inheritance by using hibernate JOINED strategy .

In this example we have a Person class which will have two fields (firstName and lastName) Person Class is Extended by Student and Teacher classes , which will share the fields of Person apart from having their own fields.

Here is the code for Base class Person . Please note that we have used @Inheritance annotation in this base class along with strategy defined as JOINED.
package com.javaroots.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {

 @Id
 @GeneratedValue
  @Column(name="person_id")
  private Long id;
 
 @Column(name="firstName")
 private String firstName;
 
 @Column(name="lastName")
    private String lastName;

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 
 
}


This is the Student class which extends Person class. We are using @PrimaryKeyJoinColumn annotation which will create a primary key named student_id for student table which will reference to person table primary key(person_id).
package com.javaroots.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
@Entity
@Table(name = "student")
@PrimaryKeyJoinColumn(name = "student_id", referencedColumnName = "person_id")
public class Student extends Person {

 @Column(name = "standard")
 private String standard;

 @Column(name = "instructor")
 private String instructor;

 public String getStandard() {
  return standard;
 }

 public void setStandard(String standard) {
  this.standard = standard;
 }

 public String getInstructor() {
  return instructor;
 }

 public void setInstructor(String instructor) {
  this.instructor = instructor;
 }

}


Similar to Student , we have another class called Teacher which will also get it's primary key(teacher_id) from person table .
package com.javaroots.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
@Entity
@Table(name = "teacher")
@PrimaryKeyJoinColumn(name = "teacher_id", referencedColumnName = "person_id")
public class Teacher extends Person{
 
 @Column(name = "main_subject")
 private String mainSubject;
 
 @Column(name = "salary")
    private int salary;
 
 @Column(name = "type")
    private String type; // Primary or Secondary School teacher

 public String getMainSubject() {
  return mainSubject;
 }

 public void setMainSubject(String mainSubject) {
  this.mainSubject = mainSubject;
 }

 public int getSalary() {
  return salary;
 }

 public void setSalary(int salary) {
  this.salary = salary;
 }

 public String getType() {
  return type;
 }

 public void setType(String type) {
  this.type = type;
 }
 
 

}


This is the test class to create entries in Student , Teacher and Person Table.
package com.javaroots.main;

import org.hibernate.Session;

import com.javaroots.model.Student;
import com.javaroots.model.Teacher;
import com.javaroots.util.HibernateUtil;

public class HibernateTest {

public static void main(String[] args) {
         
        Session session = HibernateUtil.getSessionFactory().openSession();
 
        session.beginTransaction();
        
        Student st = new Student();
        st.setInstructor("Joshua");
        st.setFirstName("James");
        st.setLastName("java roots");
        
        session.save(st);
        
        
        Teacher te = new Teacher();
        te.setMainSubject("java");
        te.setSalary(1000);
        te.setFirstName("Gosling");
        te.setLastName("opensource");
        
        session.save(te);
        session.getTransaction().commit();

    }
   
}

These are the structures of tables(person , teacher , student) . teacher and student table's primary key references to person table primary key .

CREATE TABLE `person` (
  `person_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `firstName` varchar(255) DEFAULT NULL,
  `lastName` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8$$

delimiter $$

CREATE TABLE `student` (
  `instructor` varchar(255) DEFAULT NULL,
  `standard` varchar(255) DEFAULT NULL,
  `student_id` bigint(20) NOT NULL,
  PRIMARY KEY (`student_id`),
  KEY `FK8FFE823B961B9B25` (`student_id`),
  CONSTRAINT `FK8FFE823B961B9B25` FOREIGN KEY (`student_id`) REFERENCES `person` (`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

delimiter $$

CREATE TABLE `teacher` (
  `main_subject` varchar(255) DEFAULT NULL,
  `salary` int(11) DEFAULT NULL,
  `type` varchar(255) DEFAULT NULL,
  `teacher_id` bigint(20) NOT NULL,
  PRIMARY KEY (`teacher_id`),
  KEY `FKAA31CBE28C839C1E` (`teacher_id`),
  CONSTRAINT `FKAA31CBE28C839C1E` FOREIGN KEY (`teacher_id`) REFERENCES `person` (`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$



These are the queries fired by hibernate . Whenever a teacher or student object is created , hibernate first create an entry in person table , and then creates entry in student or teacher table with the primary id of person .
Hibernate: 
    alter table student 
        drop 
        foreign key FK8FFE823B961B9B25
Hibernate: 
    alter table teacher 
        drop 
        foreign key FKAA31CBE28C839C1E
Hibernate: 
    drop table if exists person
Hibernate: 
    drop table if exists student
Hibernate: 
    drop table if exists teacher
Hibernate: 
    create table person (
        person_id bigint not null auto_increment,
        firstName varchar(255),
        lastName varchar(255),
        primary key (person_id)
    )
Hibernate: 
    create table student (
        instructor varchar(255),
        standard varchar(255),
        student_id bigint not null,
        primary key (student_id)
    )
Hibernate: 
    create table teacher (
        main_subject varchar(255),
        salary integer,
        type varchar(255),
        teacher_id bigint not null,
        primary key (teacher_id)
    )
Hibernate: 
    alter table student 
        add index FK8FFE823B961B9B25 (student_id), 
        add constraint FK8FFE823B961B9B25 
        foreign key (student_id) 
        references person (person_id)
Hibernate: 
    alter table teacher 
        add index FKAA31CBE28C839C1E (teacher_id), 
        add constraint FKAA31CBE28C839C1E 
        foreign key (teacher_id) 
        references person (person_id)
Hibernate: 
    insert 
    into
        person
        (firstName, lastName) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        student
        (instructor, standard, student_id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        person
        (firstName, lastName) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        teacher
        (main_subject, salary, type, teacher_id) 
    values
        (?, ?, ?, ?)


This is how the inheritance is implemented in hibenrate JOINED inheritance strategy.
Post Comments and Suggestions !!