Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Table Per Subclass using Annotation

The "Table Per Subclass" strategy, also known as "Joined Table Inheritance", maps each entity class to its table, but tables for subclasses only contain columns for the additional attributes specific to the subclass. Tables are connected through a primary key and foreign key relationship.

Let's explore how to implement the "Table Per Subclass" strategy using annotations in Hibernate.

1. Setting Up:

Ensure you've configured a Hibernate project with the necessary dependencies.

2. Define the Entity Classes:

Base Class (Person):

@Entity
@Table(name = "PERSON")
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    // Getters, setters, constructors...
}

Here, @Inheritance specifies the inheritance strategy.

Subclasses (Employee and Customer):

@Entity
@Table(name = "EMPLOYEE")
@PrimaryKeyJoinColumn(name = "ID")
public class Employee extends Person {

    private double salary;

    // Getters, setters, constructors...
}

@Entity
@Table(name = "CUSTOMER")
@PrimaryKeyJoinColumn(name = "ID")
public class Customer extends Person {

    private String purchasedProduct;

    // Getters, setters, constructors...
}

@PrimaryKeyJoinColumn specifies the column for joining the subclass table with the superclass table.

3. Persistence:

When creating and persisting an Employee instance:

Employee emp = new Employee();
emp.setName("John");
emp.setSalary(75000);

session.save(emp);

Hibernate will insert rows in both PERSON and EMPLOYEE tables.

4. Fetching:

When fetching an instance:

Employee retrievedEmployee = session.get(Employee.class, empId);

Hibernate will generate the necessary JOIN operations between PERSON and EMPLOYEE tables to fetch the complete Employee object.

5. Benefits & Drawbacks:

Benefits:

  • Database schema is more normalized.
  • No wasted space in tables as subclass tables only contain columns specific to them.

Drawbacks:

  • Retrieval operations can be slower due to JOIN operations.
  • Insert and update operations involve multiple tables.

Conclusion:

The "Table Per Subclass" strategy, implemented using annotations in Hibernate, provides a way to map inheritance hierarchies to a normalized relational database schema. This strategy can be a good fit when your database schema's normalization is a priority, and you are okay with potentially slower join operations for retrieval. Always consider your specific application's requirements when choosing an inheritance mapping strategy.

  1. Hibernate table per subclass mapping example:

    • Table per subclass inheritance strategy in Hibernate involves mapping each subclass to its own table.
    • Use @Entity and @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotations.
    // Parent class
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE)
        private Long id;
    
        // Common fields and methods
    }
    
    // Subclass
    @Entity
    public class Cat extends Animal {
        private String color;
    
        // Cat-specific fields and methods
    }
    
    // Subclass
    @Entity
    public class Dog extends Animal {
        private String breed;
    
        // Dog-specific fields and methods
    }
    
  2. Configuring table per subclass inheritance in Hibernate:

    • Configure table per subclass inheritance in Hibernate using @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotation on the superclass.
    // Parent class
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        // Common fields and methods
    }
    
  3. Mapping subclasses with Hibernate annotations:

    • Map subclasses using @Entity annotations for each subclass and extend the superclass.
    // Parent class
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        // Common fields and methods
    }
    
    // Subclass
    @Entity
    public class Cat extends Animal {
        // Cat-specific fields and methods
    }
    
    // Subclass
    @Entity
    public class Dog extends Animal {
        // Dog-specific fields and methods
    }
    
  4. Table per subclass vs table per hierarchy in Hibernate annotations:

    • In Hibernate annotations, table per subclass involves using separate @Entity annotations for each subclass, while table per hierarchy uses a single @Entity annotation for the entire hierarchy.
    // Table per subclass
    @Entity
    public class Cat extends Animal {
        // Cat-specific fields and methods
    }
    
    // Table per subclass
    @Entity
    public class Dog extends Animal {
        // Dog-specific fields and methods
    }
    
    // Table per hierarchy
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        // Common fields and methods
    }
    
  5. Inheritance strategies with annotations in Hibernate:

    • Hibernate supports different inheritance strategies, including SINGLE_TABLE, TABLE_PER_CLASS, and JOINED.
    • Use @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) for table per subclass.
    // Parent class
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        // Common fields and methods
    }
    
  6. Hibernate @Inheritance annotation for table per subclass:

    • Use @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotation on the superclass to specify the table per subclass inheritance strategy in Hibernate annotations.
    // Parent class
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        // Common fields and methods
    }
    
  7. Handling associations in table per subclass mapping:

    • Handle associations in table per subclass mapping by defining relationships in the annotated classes.
    // Parent class
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Animal {
        // Common fields and methods
    }
    
    // Subclass
    @Entity
    public class Cat extends Animal {
        // Cat-specific fields and methods
    
        @ManyToOne
        @JoinColumn(name = "owner_id")
        private Person owner;
    }
    
  8. HQL queries for table per subclass inheritance in Hibernate annotations:

    • Use HQL (Hibernate Query Language) for queries specific to the table per subclass strategy.
    String hql = "FROM Cat WHERE color = :color";
    Query query = session.createQuery(hql);
    query.setParameter("color", "black");
    List<Cat> blackCats = query.list();