Master java skills

Inheritance Mapping in Hibernate

Inheritance hierarchy classes can be mapped in following ways in hibernate.

  1. Table per hierarchy
  2. Table per concrete class
  3. 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>
  1. 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