Hibernate Inheritance: Table Per Subclass Hierarchy

Table per subclass hierarchy

In this article we will see how to implement Table per subclass mapping in hibernate .In this mapping each class persist the data in its own separate table.A foreign key relationship exists between the subclass tables and super class table and common data will store in to the parent class table.


Let us Consider Vehicle is parent class and Bus and Car are sub classes.Following the class diagram and relationship of these classes.


table per class


Here Vehicle is root class and Bus and Car are sub classes. Vehicle id will be as foreign key in Bus and Car table and common data(vehicleId) is stored in VEHICLE table and subclass specific fields are stored in BUS and CAR tables.

Table per subclass hierarchy

In this article we will see how to implement Table per subclass mapping in hibernate .In this mapping each class persist the data in its own separate table.A foreign key relationship exists between the subclass tables and super class table and common data will store in to the parent class table.


Let us Consider Vehicle is parent class and Bus and Car are sub classes.Following the class diagram and relationship of these classes.


table per class


Here Vehicle is root class and Bus and Car are sub classes. Vehicle id will be as foreign key in Bus and Car table and common data(vehicleId) is stored in VEHICLE table and subclass specific fields are stored in BUS and CAR tables.





Create Database Table to persist classes

CREATE TABLE `VEHICLE` (
    `vehicle_id` int NOT NULL AUTO_INCREMENT,
    `vehicle_name` VARCHAR(50),
    `type` VARCHAR(50),
    PRIMARY KEY (`vehicle_id`)
);
 
CREATE TABLE `CAR` (
    `vehicle_id` int NOT NULL,
    `car_model` VARCHAR(50),
    PRIMARY KEY (`vehicle_id`),
    CONSTRAINT `FK_CAR` FOREIGN KEY (`vehicle_id`) REFERENCES `VEHICLE` (`vehicle_id`)
);
 
CREATE TABLE `BUS` (
    `vehicle_id` int NOT NULL,
    `bus_model` VARCHAR(50),
    PRIMARY KEY (`vehicle_id`),
    CONSTRAINT `FK_BUS` FOREIGN KEY (`vehicle_id`) REFERENCES `VEHICLE` (`vehicle_id`)
);


Follow the steps mentioned bellow to create Hibernate Table Per Subclass mapping Project.


Step 1 . Create a Java project

Create a Java project and name it HibernateSubClassEx and add Hibernate jars and Mysql driver jar in to class path of this project.


Step 2 . Create Java Class Vehicle

Create a package "com.javawebtutor.hibernate" and in that package create a java class and name it to"Vehicle" .

Vehicle.java:
package com.javawebtutor.hibernate;

public class Vehicle {
	private Integer vehicleID;
	private String vehicleName;
	private String vehicleType;

	public Integer getVehicleID() {
		return vehicleID;
	}

	public void setVehicleID(Integer vehicleID) {
		this.vehicleID = vehicleID;
	}

	public String getVehicleName() {
		return vehicleName;
	}

	public void setVehicleName(String vehicleName) {
		this.vehicleName = vehicleName;
	}

	public String getVehicleType() {
		return vehicleType;
	}

	public void setVehicleType(String vehicleType) {
		this.vehicleType = vehicleType;
	}

}


Step 3 . Create a sub class (Car.java)


Car.java:
package com.javawebtutor.hibernate;

public class Car extends Vehicle {
	private String carModel;

	public String getCarModel() {
		return carModel;
	}

	public void setCarModel(String carModel) {
		this.carModel = carModel;
	}

}
Bus.java:
package com.javawebtutor.hibernate;

public class Bus extends Vehicle {
	private String busModel;

	public String getBusModel() {
		return busModel;
	}

	public void setBusModel(String busModel) {
		this.busModel = busModel;
	}

}


Step 4 . Create Hibernate configuration file(hibernate.cfg.xml)

Create hibernate.cfg.xml file inside src folder of your project.Your hibernate.cfg.xml file should always in classpath of your project.If you are creating this file in src folder it will always be in classpath of your project

hibernate-cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/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:3306/javawebtutor</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">mukesh</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="show_sql">true</property>
		<property name="format_sql">true</property>
		<property name="hbm2ddl.auto">create </property>
		<mapping resource="com/javawebtutor/hibernate/vehicle.hbm.xml" />
	</session-factory>
</hibernate-configuration>

Step 5 . Create mapping file

Now create mapping file inside "com.javawebtutor.hibernate" package".

Note that we have defined only one hibernate mapping (hbm) file vehicle.hbm.xml. Both Bus and Car model class are defined within one hbm file.

vehicle.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.javawebtutor.hibernate">

	<class name="Vehicle" table="VEHICLE">
		<id name="vehicleID" column="vehicle_id">
			<generator class="increment" />
		</id>

		<property name="vehicleName" column="vehicle_name" />
		<property name="vehicleType" column="type" />

		<joined-subclass name="Car" extends="Vehicle">
			<key column="vehicle_id" />
			<property name="carModel" column="car_model" />
		</joined-subclass>
		<joined-subclass name="Bus" extends="Vehicle">
			<key column="vehicle_id" />
			<property name="busModel" column="bus_model" />
		</joined-subclass>
	</class>
</hibernate-mapping>

In case of table per subclass class, there will be three tables in the database, each representing a particular class.

The "joined-subclass" sub element of class, specifies the subclass. The key sub element of "joined-subclass " is used to generate the foreign key in the subclass mapped table. This foreign key will be associated with the primary key of parent class mapped table.




Now create a Test class for the purpose of inserting the data into the DB

Test.java:
package com.javawebtutor.hibernate;

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

public class Test {
	public static void main(String[] args) {

		Configuration cfg = new Configuration();
		cfg.configure("hibernate.cfg.xml");
		SessionFactory factory = cfg.buildSessionFactory();
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		Vehicle vehicle = new Vehicle();
		vehicle.setVehicleID(1);
		vehicle.setVehicleName("Tata");
		vehicle.setVehicleType("Commercial");

		Car car = new Car();
		car.setVehicleName("Honda");
		car.setCarModel("City");

		Bus bus = new Bus();
		bus.setVehicleName("Airawat");
		bus.setBusModel("Volvo");

		System.out.println("Vehicle objects Saved");

		session.save(vehicle);
		session.save(car);
		session.save(bus);
		System.out.println("Object saved successfully.....!!");
		tx.commit();
		session.close();
		factory.close();
	}
}

Directory Structure of the Project

table per class


Output

When you run it,you will get following output in the eclipse console.

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Vehicle objects Saved
Hibernate: 
    select
        max(vehicle_id) 
    from
        VEHICLE
Object saved successfully.....!!
Hibernate: 
    insert 
    into
        VEHICLE
        (vehicle_name, type, vehicle_id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        VEHICLE
        (vehicle_name, type, vehicle_id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        Car
        (car_model, vehicle_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        VEHICLE
        (vehicle_name, type, vehicle_id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        Bus
        (bus_model, vehicle_id) 
    values
        (?, ?)

SQL Output

1) select * from VEHICLE

table per subclass

2) select * from CAR

table per subclass

3) select * from BUS

table per subclass

You can download the source code of the example by clicking on the Download link below.

Source : Download
Source + Lib : Download




comments powered by Disqus