- Single Table Inheritance (Single Table per Class Hierarchy)
- Table Per Class (Concrete Table Inheritance)
- Joined Table Inheritance
In this tutorial, we will explore each of these inheritance mapping strategies using examples.
Prerequisites
Before we start, ensure you have the following:
- Java Development Kit (JDK) installed
- Apache Maven installed
- MySQL database installed and running (or any other relational database)
- An IDE (such as IntelliJ IDEA, Eclipse, or VS Code) installed
Step 1: Setting Up the Hibernate Project
1.1 Create a Maven Project
-
Open your IDE and create a new Maven project.
-
Configure the
pom.xml
file:
Add the following dependencies to your pom.xml
:
<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.example</groupId>
<artifactId>hibernate-inheritance-example</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-hikaricp</artifactId>
<version>6.4.0.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.2 Configure Hibernate
Create a file named hibernate.cfg.xml
in the src/main/resources
directory with the following content:
<!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.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database_name</property>
<property name="hibernate.connection.username">your_username</property>
<property name="hibernate.connection.password">your_password</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
</session-factory>
</hibernate-configuration>
Replace your_database_name
, your_username
, and your_password
with your MySQL database credentials.
Step 2: Implementing Inheritance Strategies
2.1 Single Table Inheritance
In the Single-Table Inheritance strategy, a single table stores all the fields of the entire class hierarchy. Discriminator columns determine the type of each row.
2.1.1 Create Base Class and Subclasses
Create an Animal
class in the com.example.hibernateinheritance.model
package:
package com.example.hibernateinheritance.model;
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Animal {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Constructors, Getters, and Setters
public Animal() {}
public Animal(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Create a Dog
class that extends Animal
:
package com.example.hibernateinheritance.model;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
@Entity
@DiscriminatorValue("Dog")
public class Dog extends Animal {
private String breed;
// Constructors, Getters, and Setters
public Dog() {}
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
}
Create a Cat
class that extends Animal
:
package com.example.hibernateinheritance.model;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
@Entity
@DiscriminatorValue("Cat")
public class Cat extends Animal {
private String color;
// Constructors, Getters, and Setters
public Cat() {}
public Cat(String name, String color) {
super(name);
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
2.2 Table Per Class
In the Table Per Class strategy, each class in the hierarchy is mapped to its own table. This means that no table contains the entire hierarchy.
2.2.1 Create Base Class and Subclasses
Create a Vehicle
class in the com.example.hibernateinheritance.model
package:
package com.example.hibernateinheritance.model;
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String manufacturer;
// Constructors, Getters, and Setters
public Vehicle() {}
public Vehicle(String manufacturer) {
this.manufacturer = manufacturer;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
}
Create a Car
class that extends Vehicle
:
package com.example.hibernateinheritance.model;
import jakarta.persistence.Entity;
@Entity
public class Car extends Vehicle {
private int doors;
// Constructors, Getters, and Setters
public Car() {}
public Car(String manufacturer, int doors) {
super(manufacturer);
this.doors = doors;
}
public int getDoors() {
return doors;
}
public void setDoors(int doors) {
this.doors = doors;
}
}
Create a Bike
class that extends Vehicle
:
package com.example.hibernateinheritance.model;
import jakarta.persistence.Entity;
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Constructors, Getters, and Setters
public Bike() {}
public Bike(String manufacturer, boolean hasCarrier) {
super(manufacturer);
this.hasCarrier = hasCarrier;
}
public boolean isHasCarrier() {
return hasCarrier;
}
public void setHasCarrier(boolean hasCarrier) {
this.hasCarrier = hasCarrier;
}
}
2.3 Joined Table Inheritance
In the Joined Table Inheritance strategy, each class in the hierarchy is mapped to its own table, which is joined using a foreign key.
2.3.1 Create Base Class and Subclasses
Create a Person
class in the com.example.hibernateinheritance.model
package:
package com.example.hibernateinheritance.model;
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Constructors, Getters, and Setters
public Person() {}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Create a Student
class that extends Person
:
package com.example.hibernateinheritance.model;
import jakarta.persistence.Entity;
@Entity
public class Student extends Person {
private String course;
// Constructors, Getters, and Setters
public Student() {}
public Student(String name, String course) {
super(name);
this.course = course;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
}
Create a Teacher
class that extends Person
:
package com.example.hibernateinheritance.model;
import jakarta.persistence.Entity;
@Entity
public class Teacher extends Person {
private String subject;
// Constructors, Getters, and Setters
public Teacher() {}
public Teacher(String name, String subject) {
super(name);
this.subject = subject;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
}
Step 3: Creating the Hibernate Utility Class
Create a HibernateUtil
class in the com.example.hibernateinheritance.util
package:
package com.example.hibernateinheritance.util;
import com.example.hibernateinheritance.model.*;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
configuration.addAnnotatedClass(Animal.class);
configuration.addAnnotatedClass(Dog.class);
configuration.addAnnotatedClass(Cat.class);
configuration.addAnnotatedClass(Vehicle.class);
configuration.addAnnotatedClass(Car.class);
configuration.addAnnotatedClass(Bike.class);
configuration.addAnnotatedClass(Person.class);
configuration.addAnnotatedClass(Student.class);
configuration.addAnnotatedClass(Teacher.class);
return configuration.buildSessionFactory(new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build());
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
}
Step 4: Demonstrating Inheritance Mappings
4.1 Create a Main Class
Create a Main
class in the com.example.hibernateinheritance
package to demonstrate the inheritance mappings:
package com.example.hibernateinheritance;
import com.example.hibernateinheritance.model.*;
import com.example.hibernateinheritance.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Main {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
// Single Table Inheritance
Animal dog = new Dog("Buddy", "Golden Retriever");
Animal cat = new Cat("Kitty", "Black");
session.save(dog);
session.save(cat);
// Table Per Class
Vehicle car = new Car("Toyota", 4);
Vehicle bike = new Bike("Yamaha", true);
session.save(car);
session.save(bike);
// Joined Table Inheritance
Person student = new Student("John", "Computer Science");
Person teacher = new Teacher("Ms. Smith", "Mathematics");
session.save(student);
session.save(teacher);
transaction.commit();
session.close();
HibernateUtil.shutdown();
}
}
Conclusion
In this tutorial, we explored Hibernate's three main inheritance mapping strategies: Single Table Inheritance, Table Per Class, and Joined Table Inheritance. We demonstrated how to configure each strategy and provided examples for each. Understanding these strategies is crucial for designing efficient and maintainable data models in applications that involve complex inheritance hierarchies.
Comments
Post a Comment
Leave Comment