Hibernate Inheritance: Table Per Class hierarchy(Annotation)

Hi Guys, to my previous post i want to add annotation capability. There is not much change in the project structure but only minor changes are required. To the Person.java and Employee.java we add Annotation Capabilities, prior to adding annotations please add javaee-api-5.jar or javaee.jar in order to get the persistence annotation to your build path.

Person.java

/**
 * 
 */
package com.spark.hibernate.model;

import java.io.Serializable;

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

/**
 * @author Sony
 * 
 */
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING,name="discriminator")
@DiscriminatorValue(value="P")
public class Person implements Serializable {

	private int personId;
	private String firstName;
	private String lastName;
	
	public Person() {
		// TODO Auto-generated constructor stub
	}
	
	public Person(String firstName,String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	/**
	 * @return the personId
	 */
	@Id
	@GeneratedValue
	@Column(name="person_id")
	public int getPersonId() {
		return personId;
	}

	/**
	 * @param personId
	 *            the personId to set
	 */
	public void setPersonId(int personId) {
		this.personId = personId;
	}

	/**
	 * @return the firstName
	 */
	@Column(name="firstname")
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the lastName
	 */
	@Column(name="lastname")
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

Employee.java

/**
 * 
 */
package com.spark.hibernate.model;

import java.io.Serializable;
import java.util.Date;

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

/**
 * @author Sony
 * 
 */
@Entity
@Table(name="person")
@DiscriminatorValue(value="E")
public class Employee extends Person implements Serializable {

	private Date joiningDate;
	private String departmentName;
	
	public Employee() {
		// TODO Auto-generated constructor stub
	}
	
	public Employee(String firstName,String lastName,Date joiningDate,String departmentName) {
		super(firstName,lastName);
		this.joiningDate = joiningDate;
		this.departmentName = departmentName;
	}

	/**
	 * @return the joiningDate
	 */
	@Column(name="joining_date")
	public Date getJoiningDate() {
		return joiningDate;
	}

	/**
	 * @param joiningDate
	 *            the joiningDate to set
	 */
	public void setJoiningDate(Date joiningDate) {
		this.joiningDate = joiningDate;
	}

	/**
	 * @return the departmentName
	 */
	@Column(name="department_name")
	public String getDepartmentName() {
		return departmentName;
	}

	/**
	 * @param departmentName
	 *            the departmentName to set
	 */
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}

}

Lets have little discussion about annotation in the code above:
The Person class is at the root of hierarchy. Hence we have used some annotations to make it as the root.

@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the root of the entity class hierarchy.

@DiscriminatorColumn – Is used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies. The strategy and the discriminator column are only specified in the root of an entity class hierarchy or sub hierarchy in which a different inheritance strategy is applied

If the @DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to “DTYPE” and the discriminator type to DiscriminatorType.STRING.

@DiscriminatorValue – Is used to specify the value of the discriminator column for entities of the given type. The DiscriminatorValue annotation can only be specified on a concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.

The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if not defaulted, should be specified for each entity class in the hierarchy.

after all these major changes small tweeks are required in hibernate.cfg.xml as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//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.password">root</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.query.startup_check">true</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.use_sql_comments">true</property>
  <property name="hibernate.format_sql">true</property>
  <mapping class="com.spark.hibernate.model.Person"/>
  <mapping class="com.spark.hibernate.model.Employee"/>
  <!-- <mapping resource="com/spark/hibernate/model/Person.hbm.xml"/> -->
 </session-factory>
</hibernate-configuration>

now the helper class changes as follows:

/**
 * 
 */
package com.spark.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

/**
 * @author Sony
 *
 */
public class HibernateUtil {

	private static SessionFactory sessionFactory;
	
	public static SessionFactory getSessionFactory(){
		
		//sessionFactory = new Configuration().configure().buildSessionFactory();
		sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
		return sessionFactory;
	}
}

Now the changes are done your main class remains as it is, and the out put should be the same as the previous one.
Happy Coding 🙂

Advertisements

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