Table Per Concrete Class In Hibernate


Hôm nay mình xin giới thiệu với các bạn inheritance thể hiện table trên 1 class cụ thể .Chúng ta có mô hình database như sau : Các bạn sẻ cảm thấy có 1 sự dư thừa giữa các field . khi thiết kế chúng ta củng sẻ có những sự lựa chọn khác nhau vì vậy khi mapping sang hibernate chúng ta củng có những cách làm khác nhau. Mổi loại đều có ưu nhược điểm riêng củng như độ lớn của hệ thống .

d1

Chúng ta mapping qua class trong java và thể hiện sự thừa kế của chúng ta như sau:

d2

Trong việc mapping trên chúng ta thấy các thuộc tính lấy lặp lại trong database của 2 tbale employee và student không được thể hiện trên đây khi chúng ta thể hiện sự thừa kế trên class person

Ưu điểm : ^^! Đây là cách dể dàng nhất cho việc thừa kế khi mapping từ database qua class. ( Thường nói cách khác : Chúng ta gom các phần tử chung thành 1 class và những class cụ thể sẻ thừa kế từ class đó ).

Nhược điểm :

Dữ liệu thuộc lớp cha sẻ phải thể hiện qua tưng lớp con, và việc thừa kế này không được nên dùng =]], vì khi thay đổi 1 thuộc tình trong lớp cha chúng ta phải thay đổi all các thuộc tính cho lớp con.

Việc thừa kế này dẫn đến nhiều hạn chế đối với thể hiện đa hình và các liên kết chặt chẻ giữa các đối tượng. Thường được thay thế sử dụng SQL UNION queries.

Cấu trúng thư mục như sau:

d1

 

Đầu tiên chúng ta class Person.java như sau :

package model;

import java.util.Date;

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

@Entity
@Table(name="Person")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Person {
	@Id
	@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.TABLE_PER_CLASS để thể hiện việc mapping đến với các class cụ thể.

Class Employee.java

package model;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="Employee")
@AttributeOverrides({
	@AttributeOverride(name="firstName", column=@Column(name="FirstName")),
	@AttributeOverride(name="lastName",  column=@Column(name="LastName")),
	@AttributeOverride(name="birthDate", column=@Column(name="BirthDate")),
	@AttributeOverride(name="address",   column=@Column(name="Address"))
})
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 Student.java

package model;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name="Student")
@AttributeOverrides({
	@AttributeOverride(name="firstName", column=@Column(name="FirstName")),
	@AttributeOverride(name="lastName",  column=@Column(name="LastName")),
	@AttributeOverride(name="birthDate", column=@Column(name="BirthDate")),
	@AttributeOverride(name="address",   column=@Column(name="Address"))
})
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;
	}

}

Chúng ta thấy cả 2 class Employee vs Student là lớp con của class Person. Cách thức chúng ta mapping chúng ta sẻ hiện thực lại các thuộc tình bên lớp cha bằng cách sử dụng annotation @AttributeOverrides để thực hiện tác vụ trên. và chúng ta sẻ có 1 Set các thuộc tình tương ứng với các column trong database bên các class Con, chúng ta dùng @AttributeOverride để hiện.

Việc mapping này hổ trọ cho mối quan hê 1 – N cho việc thể hiện mối quan hệ 2 chiều, Và việc mapping này không thể hiện IDENTITY trên primary key của chúng ta. Vì primary key của chúng ta được thể hiện cho nhiều table khác nhau. Bạn không nên sử dụng Auto or Identity cho primary key của bạn.

Main của chúng ta.

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");
			person1.setPersonId(1001);			
			session.save(person1);

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

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

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

}

Kết quả :

Table Person:

d2

 

Table Employee:

d1

 

Tabl3 Student:

d3

 

 

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: