Inheritance Mapping in Hibernate
Inheritance hierarchy classes can be mapped in following ways in hibernate.
- Table per hierarchy
- Table per concrete class
- Table per sub class
1. Table per hierarchy example
We have inheritance hierarchy like above. We will map this hierarchy.
In this approach, single table is created for the entire hierarchy. The table would be like below.
Create maven project and add following dependencies
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.1.Final</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3</version>
</dependency>
</dependencies>
- Create Player class
package com.javatrainingschool;
public class Player {
private int id;
private String name;
//getter and setter methods
}
2. Create Cricketer class
package com.javatrainingschool;
public class Cricketer extends Player {
private String cricketerType;
private int jerseyNo;
//getter and setter methods
}
3. Create TennisPlayer class
package com.javatrainingschool;
public class TennisPlayer extends Player {
private int noOfMatches;
private int wonMatches;
//getter and setter methods
}
4. Create mapping file player.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>
<class name="com.javatrainingschool.Player" table="player"
discriminator-value="Player">
<id name="id">
<generator class="increment"></generator>
</id>
<discriminator column="type" type="string"></discriminator>
<property name="name"></property>
<subclass name="com.javatrainingschool.Cricketer"
discriminator-value="Cricketer">
<property name="cricketerType"></property>
<property name="jerseyNo"></property>
</subclass>
<subclass name="com.javatrainingschool.TennisPlayer"
discriminator-value="Tennis Player">
<property name="noOfMatches"></property>
<property name="wonMatches"></property>
</subclass>
</class>
</hibernate-mapping>
5. Create hibernate configuration file 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>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">org.hibernate.dialect.Oracle9iDialect</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521/xepdb1</property>
<property name="connection.username">system</property>
<property name="connection.password">test</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<mapping resource="player.hbm.xml"/>
</session-factory>
</hibernate-configuration>
6. Create main test class
package com.javatrainingschool;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class TestingMain {
public static void main(String[] args) {
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
Metadata meta = new MetadataSources(ssr).getMetadataBuilder().build();
SessionFactory factory = meta.getSessionFactoryBuilder().build();
Session session = factory.openSession();
Transaction t = session.beginTransaction();
Player p1 = new Player();
p1.setName("Neymar");
Cricketer c1 = new Cricketer();
c1.setJerseyNo(18);
c1.setName("Virat Kohli");
c1.setCricketerType("Batsman");
TennisPlayer t1 = new TennisPlayer();
t1.setName("Rafael Nadal");
t1.setNoOfMatches(143);
t1.setWonMatches(101);
session.persist(p1);
session.persist(c1);
session.persist(t1);
t.commit();
session.close();
factory.close();
System.out.println("Data saved successfully.");
}
}
Verify the table in the database
Player table should be created in the database. The type column is the additional column that specifies what type of player it is.
2. Table Per Concrete Class example
In this approach, a table for every concrete class is created. The only difference from the above example is the player.hbm.xml file. Rest all the files and classes would be same as above example.
player.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>
<class name="com.javatrainingschool.Player" table="player10">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>
<union-subclass name="com.javatrainingschool.Cricketer"
table="cricketer10">
<property name="cricketerType"></property>
<property name="jerseyNo"></property>
</union-subclass>
<union-subclass
name="com.javatrainingschool.TennisPlayer" table="tennis_player10">
<property name="noOfMatches"></property>
<property name="wonMatches"></property>
</union-subclass>
</class>
</hibernate-mapping>
After running the main class, 3 tables are created. player10, cricketer10 and tennis_player10
player10 table
cricketer10 table
tennis_player10
2. Table Per Sub Class example
In this approach, a table for every concrete class is created. And tables for subclasses are associated with the table for primary class by primary-key-foreign-key relationship. The only difference from the above example is the player.hbm.xml file. Rest all the files and classes would be same as above example.
player.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>
<class name="com.javatrainingschool.Player" table="player11">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>
<joined-subclass
name="com.javatrainingschool.Cricketer" table="cricketer11">
<key column="cid"></key>
<property name="cricketerType"></property>
<property name="jerseyNo"></property>
</joined-subclass>
<joined-subclass
name="com.javatrainingschool.TennisPlayer" table="tennis_player11">
<key column="tid"></key>
<property name="noOfMatches"></property>
<property name="wonMatches"></property>
</joined-subclass>
</class>
</hibernate-mapping>
After running the main class, 3 tables are created. player11, cricketer11 and tennis_player11
player11 table
cricketer11 table
tennis_player11