Table Per Subclass in Hibernate


Tiếp theo loạt bài Hibernate hôm nay mình giới thiệu đến phần thừa kế thứ 2 trên một subclass

Chúng ta quan sát mô hình thử thể quan hệ sau : Và thiết lập database với 3 table như trong hình.

d1

Trong mô hình trên chúng ta thấy rằng. Mổi table thừa kế từ class person của chúng ta và mổi table  có loại data riêng biệt của mình. Vì vậy chúng ta phải thể hiện Super class và Subclass riêng biệt ra 3 table khác nhau. Và chúng ta dùng Khóa ngoại ( Foreign key) để thể hiện sự tồn tại của cac subclass vs superclass với nhau.

Ưu điểm : cho việc sử dụng thừa kế này là nó không yêu cầu những thay đổi phức tạp đến database của chúng ta . Khi Supper class thì được chỉnh sửa. và nó hoạt động tốt cho các hệ thống trung bình không quá phức tạp.

Nhược điểm : Đối với những hệ thống lơn nếu chúng ta sử dụng sẻ dẫn tới vấn đề hiệu suất kém, Dẫn đến việc phát triển các subclass củng trở nên rộng ra.

 

Cấu trúc thư mục làm việc của chúng ta :

d1

Đầu tiên chúng ta tạo trong model tạo 1 class Person.java như sau

package model;

import java.util.Date;

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;

@Entity
@Table(name="Person")
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {
	@Id
	@GeneratedValue
	@Column(name="Person_Id")
	private int personId;

	@Column(name="FirstName")
	private String firstName;

	@Column(name="LastName")
	private String lastName;

	@Column(name="BirthDate")
	private Date birthDate;

	@Column(name="Address")
	private String address;

	public Person(String firstName, String lastName,
			Date birthDate, String address) {		
		this.firstName = firstName;
		this.lastName = lastName;
		this.birthDate = birthDate;
		this.address = address;
	}
	public Person() {

	}
	public int getPersonId() {
		return personId;
	}
	public void setPersonId(int personId) {
		this.personId = personId;
	}
	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;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}

}

Class Person.Java là supper class của chúng ta . Vì vậy chúng ta sẻ sử dụng 1 loại ananotation để thể hiện thừa kế root ở đây là @Inheritance nó định nghỉa loại thừa kế cho các table trong database.

@InheritanceType : Định nghĩa loại thừa kế mà chúng ta sử dụng ở đây chúng ta dùng là InheritanceType.JOINED là loại để cụ thể subclass , class mà thừa kế class Person của chúng ta với field liên kết giữa 2 table (Person_ID) . Và khi chúng ta new SubClass thì công việc JOIN 2 table sẻ được thực hiện . Các field chúng ta khởi tạo từ supper class sẻ được hiển thị trong table person, và các file riêng biệt của class Sutdent, Employee sẻ được thể hiện riêng trong table của chúng.

Tiếp theo chúng ta sẻ Tạo Class Student.java vs Employee.Java

package model;

import java.util.Date;

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

@Entity
@Table(name="Student")
@PrimaryKeyJoinColumn(name="Person_ID")
public class Student extends Person{
	@Column(name="School_Name")
	private String schoolName;

	@Column(name="Major")
	private String major;

	@Column(name="Degree")
	private String degree;

	public Student(String firstName, String lastName,
			Date birthDate, String address, String schoolName, String major,
			String degree) {
		super(firstName, lastName, birthDate, address);
		this.schoolName = schoolName;
		this.major = major;
		this.degree = degree;
	}

	public Student() {

	}

	public String getSchoolName() {
		return schoolName;
	}

	public void setSchoolName(String schoolName) {
		this.schoolName = schoolName;
	}

	public String getMajor() {
		return major;
	}

	public void setMajor(String major) {
		this.major = major;
	}

	public String getDegree() {
		return degree;
	}

	public void setDegree(String degree) {
		this.degree = degree;
	}

}

Class Employee.java

package model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
@Entity
@Table(name="Employee")
@PrimaryKeyJoinColumn(name="Person_ID")
public class Employee extends Person{
@Column(name="Position")
private String posotion;
@Column(name="Salary")
private String salary;
@Column(name="Division")
private String devision;

public Employee(String firstName, String lastName,
Date birthDate, String address, String position, String salary, String devision) {
super(firstName, lastName, birthDate, address);
this.posotion = position;
this.salary = salary;
this.devision = devision;
}
public Employee() {

}
public String getPosotion() {
return posotion;
}
public void setPosotion(String posotion) {
this.posotion = posotion;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getDevision() {
return devision;
}
public void setDevision(String devision) {
this.devision = devision;
}
}

Class Employee.java và Class Student.java là subclass của Person Class. Vì vậy để mapping chúng với nhau chúng ta sử dụng annotation @PrimaryKeyJoinColumn thể hiện column mapping với super class ( Person class). Nó cụ thể primary key của class Person với foreign key của class Employee vs Student ( ở đây là Person_ID )

Note :ngoại trừ dùng @PrimaryKeyJoinColumn , chúng ta có thể dùng các annotation khác như @SecondaryTable or @OneToOne để thể hiện sự liên kết giữa 2 khóa với nhau.
Nếu không dùng @PrimaryKeyJoinColumn . thì subclass sẻ tự động mapping với column là khóa chính của super class.

Chúng ta viết hàm main và run test :

package test;

import java.util.Calendar;
import java.util.Date;

import model.Employee;
import model.Person;
import model.Student;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public class TestMain {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		SessionFactory sessionFactory = HibernateUtil.getSeesionfactory();
		Session session = sessionFactory.openSession();
		Transaction trns = null;
		try {
			trns = session.beginTransaction();

			Person person1 = new Person("Hoang", "Hai", new Date(1991,10,10), "362/12/18 TN GV");
			Person person2 = new Person("Kobee", "Bryan", new Date(1991,10,20), "24/3Y TN GV");

			session.save(person1);
			session.save(person2);

			Employee employee = new Employee("Jeeny", "Tran", new Date(1992,05,18), "So 126 TN GV",
							"Java-Developer", "$1000", "ICT");
			session.save(employee);

			Student student = new Student("Ken", "Bom", Calendar.getInstance().getTime(), "So 1 QT, HN",
					"IUH University HCM", "Computing Sience", "College");
			session.save(student);
			trns.commit();

		} catch (Exception e) {
			if(trns != null)
				trns.rollback();
			e.printStackTrace();
		}finally{
			session.close();
		}
	}

}

Kết quả sau khi run :

Table Person:

d1

 

Table Student

d1

 

Table Employee

d1

 

Chúc các bạn thành công.

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

%d bloggers like this: