Hibernate Inheritance: Table Per Concrete Class Hierarchy

Table Per Concrete Class Hierarchy

In this article we will see how to implement Table per concrete class mapping in hibernate .In this mapping,One table will be created for each concrete class.


Lets say we have following class hierarchy,we have Flight class as base class and InternationalFlight and DomesticFlight inherits from Flight class.


table per class


In table per concrete class ,One table will be created for each concrete class.So in this case three table will be created.Name of the tables are FLIGHT,INT_FLIGHT and DOM_FLIGHT.In this scheme, the mapping of the subclass repeats the properties of the parent class.

Table Per Concrete Class Hierarchy

In this article we will see how to implement Table per concrete class mapping in hibernate .In this mapping,One table will be created for each concrete class.


Lets say we have following class hierarchy,we have Flight class as base class and InternationalFlight and DomesticFlight inherits from Flight class.


table per class


In table per concrete class ,One table will be created for each concrete class.So in this case three table will be created.Name of the tables are FLIGHT,INT_FLIGHT and DOM_FLIGHT.In this scheme, the mapping of the subclass repeats the properties of the parent class.







Following are the advantages and disadvantages of Table per Concrete Class Mapping

Advantages

  1. This is the easiest method of Inheritance mapping to implement.

Disadvantages

  1. Data thats belongs to a parent class is scattered across a number of subclass tables, which represents concrete classes.
  2. This hierarchy is not recommended for most cases.
  3. Changes to a parent class is reflected to large number of tables.

Create Database Table to persist classes

CREATE TABLE `FLIGHT` (
`flight_id` int NOT NULL AUTO_INCREMENT,
`flight_name` VARCHAR(50) NOT NULL DEFAULT '0',
`flight_model` VARCHAR(50) NOT NULL DEFAULT '0',
PRIMARY KEY (`flight_id`)
)

CREATE TABLE `DOM_FLIGHT` (
`flight_id` int NOT NULL AUTO_INCREMENT,
`flight_name` VARCHAR(50) NOT NULL DEFAULT '0',
`flight_model` VARCHAR(50) NOT NULL DEFAULT '0',
`departure_city` VARCHAR(50) NULL DEFAULT NULL,
`arrival_city` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`flight_id`)
)

CREATE TABLE `INT_FLIGHT` (
`flight_id` int NOT NULL AUTO_INCREMENT,
`flight_name` VARCHAR(50) NOT NULL DEFAULT '0',
`flight_model` VARCHAR(50) NOT NULL DEFAULT '0',
`pilot_name` VARCHAR(50) NULL DEFAULT NULL,
`departure_country` VARCHAR(50) NULL DEFAULT NULL,
`arrival_country` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`flight_id`)
)

As per class diagram,we need to create three classes- Flight.java,DomesticFlight.java and IntFlight.java.

Step 1 . Create a Java project

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



Step 2 . Create Java Class Flight

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

Flight.java:
package com.jwt.hibernate;

public class Flight {
	private Integer flightId;
	private String flightName;
	private String flightModel;

	public Integer getFlightId() {
		return flightId;
	}

	public void setFlightId(Integer flightId) {
		this.flightId = flightId;
	}

	public String getFlightName() {
		return flightName;
	}

	public void setFlightName(String flightName) {
		this.flightName = flightName;
	}

	public String getFlightModel() {
		return flightModel;
	}

	public void setFlightModel(String flightModel) {
		this.flightModel = flightModel;
	}

}

Step 3 . Create Sub Class


DomesticFlight.java:
package com.jwt.hibernate;

public class DomesticFlight extends Flight {
	private String departureCity;
	private String arrivalCity;

	public String getDepartureCity() {
		return departureCity;
	}

	public void setDepartureCity(String departureCity) {
		this.departureCity = departureCity;
	}

	public String getArrivalCity() {
		return arrivalCity;
	}

	public void setArrivalCity(String arrivalCity) {
		this.arrivalCity = arrivalCity;
	}

}

InternationalFlight.java:
package com.jwt.hibernate;

public class InternationalFlight extends Flight {
	private String pilot;
	private String departureCountry;
	private String arrivalCountry;

	public String getPilot() {
		return pilot;
	}

	public void setPilot(String pilot) {
		this.pilot = pilot;
	}

	public String getDepartureCountry() {
		return departureCountry;
	}

	public void setDepartureCountry(String departureCountry) {
		this.departureCountry = departureCountry;
	}

	public String getArrivalCountry() {
		return arrivalCountry;
	}

	public void setArrivalCountry(String arrivalCountry) {
		this.arrivalCountry = arrivalCountry;
	}

}

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/jwt</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">update </property>
		<mapping resource="com/jwt/hibernate/flight.hbm.xml" />
	</session-factory>
</hibernate-configuration>

Step 5 . Create mapping file

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

Note that we have defined only one hibernate mapping (hbm) file flight.hbm.xml. Both DomesticFlight and nternationalFlight model class are defined within one hbm file.

flight.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.jwt.hibernate">

	<class name="Flight" table="FLIGHT">
		<id name="flightId" column="flight_id">
			<generator class="native" />
		</id>
		<property name="flightName" column="flight_name" />
		<property name="flightModel" column="flight_model" />

	</class>

	<class name="DomesticFlight" table="FLIGHT">
		<id name="flightId" column="flight_id">
			<generator class="native" />
		</id>
		<property name="departureCity" column="departure_city" />
		<property name="arrivalCity" column="arrival_city" />

	</class>

	<class name="InternationalFlight" table="FLIGHT">
		<id name="flightId" column="flight_id">
			<generator class="native" />
		</id>
		<property name="pilot" column="pilot_name" />
		<property name="departureCountry" column="departure_country" />
		<property name="arrivalCountry" column="arrival_country" />
	</class>
</hibernate-mapping>

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

Test.java:
package com.jwt.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();
 
        Flight flight = new Flight();
        flight.setFlightId(101);
        flight.setFlightName("Indigo");
        flight.setFlightModel("A380");
        
        Flight flight1 = new Flight();
        flight1.setFlightId(201);
        flight1.setFlightName("Air Asia");
        flight1.setFlightModel("A480");
        
        DomesticFlight domesticFlight = new DomesticFlight();
        domesticFlight.setFlightId(101);
        domesticFlight.setFlightName("Indigo");
        domesticFlight.setFlightModel("A380");
        domesticFlight.setDepartureCity("New Delhi");
        domesticFlight.setArrivalCity("Chennai");
        
        InternationalFlight internationalFlight = new InternationalFlight();
        internationalFlight.setFlightId(201);
        internationalFlight.setFlightModel("A480");
        internationalFlight.setFlightName("Air Asia");
        internationalFlight.setDepartureCountry("India");
        internationalFlight.setArrivalCountry("Texas");
       
        Transaction tx = session.beginTransaction();
        session.save(flight);
        session.save(flight1);
        session.save(domesticFlight);
        session.save(internationalFlight);
        System.out.println("Object saved successfully.....!!");
        tx.commit();
        session.close();
        factory.close();
    }
 
}

Directory Structure of the Project

table per concrete 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.
Hibernate: 
    insert 
    into
        FLIGHT
        (flight_name, flight_model) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        FLIGHT
        (flight_name, flight_model) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        DOM_FLIGHT
        (departure_city, arrival_city) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        INT_FLIGHT
        (pilot_name, departure_country, arrival_country) 
    values
        (?, ?, ?)
Object saved successfully.....!!

SQL Output

1) select * from FLIGHT

table per subclass

2) select * from DOM_FLIGHT;

table per subclass

3) select * from INT_FLIGHT;

table per subclass

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

Source + Lib : Download


comments powered by Disqus