Table Per Class Hierarchy In Hibernate


Hôm nay mình giới thiệu các bạn đến với Hibernate Hierarchy .

Source code : Download

Chúng ta biết rằng Java là một ngôn ngữ hướng đối tượng. Chúng ta thường xuyên thể hiện thừa kế trong java. Khái niệm thừa kế là một trong nhưng tính năng khá quan trong của môn ngôn ngữ và điều này củng được chúng ta mapping đến CSDL . Chúng ta có 2 mối quan hệ quan tâm trong hệ thống hướng đối tượng là Is-A và Has-A. Nhưng bạn cần có 1 sự lựa chon thích hợp cho mô hình quan hệ của bạn. Ví dụ này mình hướng tới thừa kết trên 1 class . Chúng ta có mô hình thừa kế như sau d1

Trong One Table Per Class Hierachy . Chúng ta lưu trữ all các class thừa kế này trong duy nhất 1 Table tring SQL của chúng ta thôi. Để phân biệt giữa các class với nhau trong table ta thêm 1 field để phân biệt các class với nhau (Discriminator ). Việc sử dụng One Table Per Class Hierachy này cúng cấp tốt trong việc thể hiện độ sâu của thừa kế trong các class. Nhưng bất lợi chúng ta gặp khi có 1 sự thay đổi số lượng các field trong class thì yêu cầu chúng ta củng phải thay đổi trong database .

d1

Cấu trúc thư mục :

d1

Chúng tạo ra class Employee.java

package thaihoanghai.hibernate.bean;

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.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

@Entity
@Table(name="Employee")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue(value="E")
public class Employee {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="id")
	private int id;
	@Column(name="name")
	private String name;

	public Employee() {

	}
	public Employee(int id, String name) {
		this.id = id;
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

}

Tiếp theo chúng ta tạo ra 2 class Contract_Employee.java va Regular_Employee.java

Contract_Employee.java

package thaihoanghai.hibernate.bean;

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

@Entity
@Table(name="Employee")
@DiscriminatorValue("CE")
public class Contract_Employee extends Employee{
	@Column(name="pay_per_hour")
	private float pay_per_hour;
	@Column(name="contract_duration")
	private String contract_duration;

	public float getPay_per_hour() {
		return pay_per_hour;
	}
	public void setPay_per_hour(float pay_per_hour) {
		this.pay_per_hour = pay_per_hour;
	}
	public String getContract_duration() {
		return contract_duration;
	}
	public void setContract_duration(String contract_duration) {
		this.contract_duration = contract_duration;
	}

}

Class employee là class root của cây thừa kế chúng ta. Vì vậy chúng ta cần có những annotations để tạo ra root class

@Inheritance : Định nghĩa loại thừa kế được sử dụng cho class hierarchy. Nó được sữ dụng trên class nào mà bạn xem n
ó là class root trong thừa kệ

@DiscriminatorColumn : Nó sử dụng để định nghĩa column mà chúng ta dùng để phân biệt giữa các class thừa kế. Và nó được thể hiện trong class root và class sub root. Nếu chúng ta không thiết lập thông số cho nó mặc định column sẻ là DTYPE và DiscriminatorType.String.

@DiscriminatorValue : Dùng để định nghĩa class mà chúng ta thiết lập với @DiscriminatorColumn được định từ trước

Class Regular_Employee.java

package thaihoanghai.hibernate.bean;

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

@Entity
@Table(name="Employee")
@DiscriminatorValue("RE")
public class Regular_Employee extends Employee{
	@Column(name="salary")
	private float salary;
	@Column(name="bonus")
	private int bonus;

	public float getSalary() {
		return salary;
	}
	public void setSalary(float salary) {
		this.salary = salary;
	}
	public int getBonus() {
		return bonus;
	}
	public void setBonus(int bonus) {
		this.bonus = bonus;
	}

}

Class hibernateUtil.java

package thaihoanghai.hibernate.util;

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

/**
 * Hibernate Util used to configure Hibernate's Session Factoru and retrieve it as Singleton
 * @author kobee
 *
 */
public class HibernateUtil {
	private static final SessionFactory seesionFactory;
	private static ServiceRegistry serviceRegistry;

	static{
		try {
			Configuration configuration = new Configuration();
			configuration.configure();
			serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 
			seesionFactory = configuration.buildSessionFactory(serviceRegistry);

		} catch (HibernateException e) {
			System.err.println("Initial SessionFactory creation failed. " + e);
			throw new ExceptionInInitializerError(e);
		}

	}

	public static SessionFactory getSeesionfactory() {
		return seesionFactory;
	}

}

Class Config của chúng ta:

</pre>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
 <session-factory>
 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 <property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
 <property name="hibernate.connection.username">root</property>
 <property name="hibernate.connection.password">123456</property>
 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

 <!-- JDBC connecition pool (use the built-in) -->
 <property name="hibernate.connection.pool_size">1</property>
 <!-- Enable Hibernate's automatic session context management -->
 <property name="hibernate.current_session_context_class">thread</property>

 <!-- Echo all executed SQL to stdout -->
 <property name="show_sql">true</property>
 <property name="format_sql">false</property>
 <property name="hbm2ddl.auto">Validate</property>

 <!-- Mapping to Resource -->
 <mapping class="thaihoanghai.hibernate.bean.Employee"/>
 <mapping class="thaihoanghai.hibernate.bean.Contract_Employee"/>
 <mapping class="thaihoanghai.hibernate.bean.Regular_Employee"/>

</session-factory>
</hibernate-configuration>
<pre>

Ok chúng ta viết class test lại chương trình :

package thaihoanghai.hibernate.util;

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

import thaihoanghai.hibernate.bean.Contract_Employee;
import thaihoanghai.hibernate.bean.Employee;
import thaihoanghai.hibernate.bean.Regular_Employee;

public class MainTest {
	public static void main(String[] args) {
		SessionFactory sessionFactory = HibernateUtil.getSeesionfactory();
		Session session = sessionFactory.openSession();
		Transaction trns = null;
		try {
			trns = session.beginTransaction();
			Employee e1 = new Employee();
			e1.setName("Kobee");

			Regular_Employee e2 = new Regular_Employee();
			e2.setName("Jenny");
			e2.setSalary(55000);
			e2.setBonus(5);

			Contract_Employee e3 = new Contract_Employee();
			e3.setName("Justina");
			e3.setPay_per_hour(1000);
			e3.setContract_duration("15 Hours");

			session.save(e1);
			session.save(e2);
			session.save(e3);

			trns.commit();

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

Ok sau đây là kết quả khi chạy

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: