Hibernate Inheritance: Table Per SubClass hierarchy(annotations)

Hi guys, here i am going to explain how to implement table per subclass hierarchy using annotations. with a little change to my previous post we can achieve this strategy.

just change all the Entity’s to annotated style as shown below.
AccountHolder.java

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

import java.io.Serializable;

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 Sony
 * 
 */
@Entity
@Table(name="account_holder")
@Inheritance(strategy=InheritanceType.JOINED)
public class AccountHolder implements Serializable {

	private int accountId;
	private String firstName;
	private String lastName;

	public AccountHolder() {

	}
	
	public AccountHolder(String firstName,String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}
	
	/**
	 * @return the accountId
	 */
	@Id
	@GeneratedValue
	@Column(name="account_id")
	public int getAccountId() {
		return accountId;
	}

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

	/**
	 * @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;
	}

}

Account.java

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

import java.io.Serializable;

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

/**
 * @author Sony
 * 
 */
@Entity
@Table(name="account")
@PrimaryKeyJoinColumn(name="account_id")
public class Account extends AccountHolder implements Serializable {

	private int rateOfInterest;
	private String accountType;

	public Account() {
		// TODO Auto-generated constructor stub
	}

	public Account(String firstName,String lastName,int rateOfInterest,String accountType) {
		super(firstName,lastName);
		this.rateOfInterest = rateOfInterest;
		this.accountType = accountType;
	}

	/**
	 * @return the rateOfInterest
	 */
	@Column(name="rate_of_interest")
	public int getRateOfInterest() {
		return rateOfInterest;
	}

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

	/**
	 * @return the accountType
	 */
	@Column(name="account_type")
	public String getAccountType() {
		return accountType;
	}

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

}

AccountTransactions.java

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

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

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

/**
 * @author Sony
 * 
 */
@Entity
@Table(name="account_transactions")
@PrimaryKeyJoinColumn(name="account_id")
public class AccountTransactions extends AccountHolder implements Serializable {

	private int transactionAmount;
	private String transactionType;
	private Date transactionDate;

	public AccountTransactions() {
		// TODO Auto-generated constructor stub
	}

	public AccountTransactions(String firstName, String lastName,
			int transactionAmount, String transactionType, Date transactionDate) {

		super(firstName, lastName);
		this.transactionAmount = transactionAmount;
		this.transactionDate = transactionDate;
		this.transactionType = transactionType;
	}

	/**
	 * @return the transactionAmount
	 */
	@Column(name="transaction_amount")
	public int getTransactionAmount() {
		return transactionAmount;
	}

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

	/**
	 * @return the transactionType
	 */
	@Column(name="transaction_type")
	public String getTransactionType() {
		return transactionType;
	}

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

	/**
	 * @return the transactionDate
	 */
	@Column(name="transaction_date")
	public Date getTransactionDate() {
		return transactionDate;
	}

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

}

Now little explanation regarding the annotations follows,
The AccountHolder class is 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 entity class that is the root of the entity class hierarchy.

@InheritanceType – Defines inheritance strategy options. JOINED is a strategy in which fields that are specific to a subclass are mapped to a separate table than the fields that are common to the parent class, and a join is performed to instantiate the subclass. Thus fields of Account (accountType, rateOfIntrest) and AccountTransactions (transactionAmount etc) are mapped to their respective tables.Both Account and AccountTransactions classes are child of AccountHolder class. Thus while specifying the mappings, we used @PrimaryKeyJoinColumn to map it to parent table.

@PrimaryKeyJoinColumn – This annotation specifies a primary key column that is used as a foreign key to join to another table.

It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass, it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity.

Note: If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass

Now lets change the configuration file to identify these annotated entities.

<?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.AccountHolder"/>
  <mapping class="com.spark.hibernate.model.Account"/>
  <mapping class="com.spark.hibernate.model.AccountTransactions"/>
  
 </session-factory>
</hibernate-configuration>

That is it, with the help of HibernateUtil and Main from the previous post you can run this code.
output:
Table_Per_Sub_Class
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