Spring3+Hibernate3+FusionChartsXT for reporting

Hello all, from past few days i was working on some reports and dashboards so the requirement is to call some spring services, which return the data in the form of JSON. my responsibility is to receive the JSON data and feed it to correct chart and render it so im here to share my experience in the form of small example.

please create a database as shown below:

DROP TABLE IF EXISTS `test`.`maps`;
CREATE TABLE  `test`.`maps` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `STATE_NAME` varchar(100) NOT NULL,
  `STATE_CODE` varchar(10) NOT NULL,
  `POPULATION` varchar(5) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

please download the fusionchartsXT latest(trail) version from here, after you download, create a mavanized project in eclipse.
In the pom.xml please add the below content.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spark.spring.fusioncharts</groupId>
	<artifactId>SpringFusionCharts</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>SpringFusionCharts</name>
	<description>SpringFusionCharts</description>

	<properties>
		<jdk.version>1.6</jdk.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>net.sf.ezmorph</groupId>
			<artifactId>ezmorph</artifactId>
			<version>1.0.6</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.1</version>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.8.3</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate</artifactId>
			<version>3.5.4-Final</version>
			<type>pom</type>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.5.4-Final</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.15</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.5.6</version>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.12.1.GA</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>SpringFusionCharts</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-eclipse-plugin</artifactId>
				<version>2.9</version>
				<configuration>
					<downloadSources>true</downloadSources>
					<downloadJavadocs>false</downloadJavadocs>
					<wtpversion>2.0</wtpversion>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

once this step is done all your dependencies(jar files) are managed my maven.now go and create “WEB-INF,charts,javascript” folders in src/main/webapp. In WEB-INF please put web.xml as follows.

<web-app id="WebApp_ID" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
	
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-context.xml</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>/spring/*</url-pattern>
	</servlet-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

After this step please extract the downloaded FusionChartsXT.zip in desired location, from that navigate to the folder charts, copy all the swf files and put them in the charts folder of your eclipse(src/main/webapp/charts)
now again from the FusionChartsXT home copy “FusionCharts.js,Jquery.min.js” and put them in javascript folder of your eclipse.
Now it’s time to code logic.Lets integrate Spring and Hibernate to query the database and here i transform the
result from database to JSON format, and return that to JSP.

Note: please create separate packages for interfaces and their implementations as it gives the project a clear separation between layers(good practice)

Let us see the ServiceLayer:

package com.spark.spring.fusioncharts.service;

import java.util.List;

import com.spark.spring.fusioncharts.model.Maps;

public interface GetStatasticsDataService {

	public List<Maps> getPopulationByCountry();
}

/**
 * 
 */
package com.spark.spring.fusioncharts.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.spark.spring.fusioncharts.dao.GetStatasticsData;
import com.spark.spring.fusioncharts.model.Maps;
import com.spark.spring.fusioncharts.service.GetStatasticsDataService;

/**
 * @author Sony
 *
 */
@Service(value="GetStatasticsDataServiceImpl")
public class GetStatasticsDataServiceImpl implements GetStatasticsDataService {

	@Autowired
	GetStatasticsData getStatasticsData;
	
	/* (non-Javadoc)
	 * @see com.spark.spring.fusioncharts.service.GetStatasticsDataService#getOilConsumebyCountry()
	 */
	@Override
	public List<Maps> getPopulationByCountry() {
		
		return getStatasticsData.getOilConsumebyCountry();
	}

}

Let us see the DAOLayer:

/**
 * 
 */
package com.spark.spring.fusioncharts.dao;

import java.util.List;

import com.spark.spring.fusioncharts.model.Maps;

/**
 * @author Sony
 *
 */
public interface GetStatasticsData {

	public List<Maps> getPopulationByCountry();
}

/**
 * 
 */
package com.spark.spring.fusioncharts.dao.impl;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.spark.spring.fusioncharts.dao.GetStatasticsData;
import com.spark.spring.fusioncharts.model.Maps;

/**
 * @author Sony
 *
 */
@Repository(value="GetStatasticsDataImpl")
public class GetStatasticsDataImpl extends HibernateDaoSupport implements GetStatasticsData{

	@Autowired
	public void init(SessionFactory factory) {
	    setSessionFactory(factory);
	}
	
	@Override
	public List<Maps> getPopulationByCountry() {
		
		List<Maps> mapsList = getHibernateTemplate().loadAll(Maps.class);
		return mapsList;
	}

}

Let us see the ModelLayer:

package com.spark.spring.fusioncharts.model;

import java.io.Serializable;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * <p>Pojo mapping TABLE maps</p>
 * <p></p>
 *
 * <p>Generated at Sun Jun 30 20:56:48 IST 2013</p>
 * @author Salto-db Generator v1.0.16 / EJB3
 * 
 */
@Entity
@Table(name = "maps")
@SuppressWarnings("serial")
public class Maps implements Serializable {

	/**
	 * Attribute id.
	 */
	private Integer id;
	
	/**
	 * Attribute stateName.
	 */
	private String stateName;
	
	/**
	 * Attribute stateCode.
	 */
	private String stateCode;
	
	/**
	 * Attribute population.
	 */
	private String population;
	
	
	/**
	 * <p> 
	 * </p>
	 * @return id
	 */
	@Basic
	@Id
	@GeneratedValue
	@Column(name = "ID")
		public Integer getId() {
		return id;
	}

	/**
	 * @param id new value for id 
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	
	/**
	 * <p> 
	 * </p>
	 * @return stateName
	 */
	@Basic
	@Column(name = "STATE_NAME", length = 100)
		public String getStateName() {
		return stateName;
	}

	/**
	 * @param stateName new value for stateName 
	 */
	public void setStateName(String stateName) {
		this.stateName = stateName;
	}
	
	/**
	 * <p> 
	 * </p>
	 * @return stateCode
	 */
	@Basic
	@Column(name = "STATE_CODE", length = 10)
		public String getStateCode() {
		return stateCode;
	}

	/**
	 * @param stateCode new value for stateCode 
	 */
	public void setStateCode(String stateCode) {
		this.stateCode = stateCode;
	}
	
	/**
	 * <p> 
	 * </p>
	 * @return population
	 */
	@Basic
	@Column(name = "POPULATION", length = 5)
		public String getPopulation() {
		return population;
	}

	/**
	 * @param population new value for population 
	 */
	public void setPopulation(String population) {
		this.population = population;
	}
}

Let us see the ControllerLayer:

/**
 * 
 */
package com.spark.spring.fusioncharts.controller;

import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.spark.spring.fusioncharts.model.Maps;
import com.spark.spring.fusioncharts.service.GetStatasticsDataService;

/**
 * @author Sony
 *
 */
@Controller
public class ChartsController {
	
	@Autowired
	GetStatasticsDataService getStatasticsDataService;

	@RequestMapping(value="/charts")
	public @ResponseBody String getChartsDashboard(){
		List<Maps> oilconsumebycountries = getStatasticsDataService.getPopulationByCountry();
		JSONArray jsonArray = (JSONArray)JSONSerializer.toJSON(oilconsumebycountries);
		return jsonArray.toString();
	}
	
	

}

Now let’s start looking at the resource files inorder to configure the application.

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/jdbc
            http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

	<context:component-scan base-package="com.spark.spring.fusioncharts"></context:component-scan>
	<context:annotation-config></context:annotation-config>
	<mvc:annotation-driven></mvc:annotation-driven>

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/test" />
		<property name="username" value="root" />
		<property name="password" value="root" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
		<property name="configurationClass">
			<value>org.hibernate.cfg.AnnotationConfiguration</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
	</bean>
</beans>

spring-context

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

	<!-- Enables the Spring MVC @Controller programming Model -->
	<context:component-scan base-package="com.spark.spring.fusioncharts"></context:component-scan>
	<context:annotation-config></context:annotation-config>
	<annotation-driven></annotation-driven>

	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix">
			<beans:value>/WEB-INF/pages/</beans:value>
		</beans:property>
		<beans:property name="suffix">
			<beans:value>.jsp</beans:value>
		</beans:property>

	</beans:bean>

</beans:beans>

hibernate.cfg.xml

<?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>
        <mapping class="com.spark.spring.fusioncharts.model.Maps" />
    </session-factory>
</hibernate-configuration>

log4j.properties

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=D\:\\logger.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
# Root logger option
#log4j.rootLogger=debug, file, stdout
log4j.rootLogger=info, ROOT, file
#log4j.rootLogger=fatal, file, stdout
#log4j.rootLogger=ERROR, file, stdout

Now lets code the view(JSP) part of our project.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>spring3.2+Fusion Charts</title>
<script type="text/javascript" src="javascript/jquery.min.js"></script>
<script type="text/javascript" src="javascript/FusionCharts.js"></script>
<script type="text/javascript" src="javascript/Mycharts.js"></script>
</head>
<body>
	<div style="width: 1300px;">
		<div id="piechartContainer" style="float: left; width: 600px;">FusionCharts XT will load here!</div>
		<div id="barchartContainer" style="float: right; width: 600px;">FusionCharts XT will load here!</div>
		<br style="clear: left;" />
	</div>
	
	<div style="width: 1300px;">
		<div id="pyramidchartContainer" style="float: left; width: 600px;">FusionCharts XT will load here!</div>
		<div id="linechartContainer" style="float: right; width: 600px;">FusionCharts XT will load here!</div>
		<br style="clear: left;" />
	</div>

</body>
</html>

inorder to render the charts in our dashboard please write your own javascript code as follows
Mycharts.js

$(document).ready(
		function() {
			$.ajax({
				url : "http://localhost:8080/SpringMVC/spring/charts",
				dataType : "json",
				success : function(data) {
					
					var dataObjectArray = new Array();
					
					var myPieChart = new FusionCharts("Charts/Pie3D.swf",
							"myChartId", "750", "450", "0");
					var myBarChart = new FusionCharts("Charts/Column3D.swf",
							"myChartId2", "750", "450", "0");
					var myLineChart = new FusionCharts("Charts/Line.swf",
							"myChartId3", "750", "450", "0");
					var myPyramidChart = new FusionCharts("Charts/Pyramid.swf",
							"myChartId3", "750", "450", "0");

					var dataStr = {
						'chart' : {
							'caption' : 'population per state',
							'xAxisName' : 'states',
							'yAxisName' : 'population',
							'numberPrefix' : ''
						},
						'data' : [ ]
					};

					$.each(data, function(key, value) {
						//alert(value.population + "" + value.stateName);
						var dataObject = {
								label:'',
								value:''
							}
						dataObject.label = value.stateName;
						dataObject.value = value.population;
						dataObjectArray.push(dataObject);
					});
					
					dataStr.data = dataObjectArray;
					myPieChart.setJSONData(dataStr);
					myPieChart.render("piechartContainer");

					myBarChart.setJSONData(dataStr);
					myBarChart.render("barchartContainer");

					myLineChart.setJSONData(dataStr);
					myLineChart.render("linechartContainer");

					myPyramidChart.setJSONData(dataStr);
					myPyramidChart.render("pyramidchartContainer");

				},
				error : function(data) {

				}
			});
		});

once done please run the poject and in browser it shows as below. report of same data with four different charts.
FusionChartsReport

Happy Coding:)

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 🙂