This repository contains a SpringBoot jpa project named jpa-hibernate-strategies that demonstrate the different types of strategies in JPA/Hibernate.
show databases ;
#CREATE USER 'sammy'@'localhost' IDENTIFIED BY 'password';
CREATE USER inheritance_strategies_demo_user;
GRANT ALL PRIVILEGES ON inheritance_strategies_demo.* TO 'inheritance_strategies_demo_user';
SELECT user FROM mysql. user
-
MappedSuperclass:
- Class annotated with @MappedSuperclass no longer need @Entity Annotation.
- It won’t be persisted in the database by itself.
- Provide Getter Setter Of the Super class, so that Child can access inherited fields.
-
-
@MappedSuperclass public class ParentClass { //... } @Entity public class Child1 extends ParentClass { // ... } @Entity public class Child2 extends ParentClass { // ... }
-
-
Single Table:
- This strategy creates only one table for a class hierarchy.
- JPA also chooses this strategy by default if we don’t specify one explicitly.
- Use annotation @Inheritance for inheritanceType to the superclass.
- Since the records for all entities will be in the same table. Hibernate needs a way to differentiate between them.
-
- By default, this is done through a discriminator column called DTYPE that has the name of the entity as a value - see below query generated by Hibernate if we dont use @Inheritance annotation on parent class
create table st_person (dtype varchar(31) not null, id integer not null, name varchar(255), salary float(53), course varchar(255), primary key (id)) engine=InnoDB
- To customize the discriminator column, we can use the @DiscriminatorColumn annotation. Note here, We can use @DiscriminatorColumn annotation without using @Inheritance annotation as we know it is default strategy
-
-
@Entity(name="tableName") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="column_type", discriminatorType = DiscriminatorType.INTEGER) public class ParentClass { // ... } @Entity @DiscriminatorValue("1") public class Child1 extends ParentClass { // ... } @Entity @DiscriminatorValue("2") public class Child2 extends ParentClass { // ... }
-
-
Joined Table:
- This strategy creates one table for every class including parent class.
- Primary key of parent table is used as foreign key in tables of subclasses.
-
-
@Entity(name="tableName") @Inheritance(strategy = InheritanceType.JOINED) public class ParentClass { // ... } @Entity @PrimaryKeyJoinColumn(name = "child1_id") public class Child1 extends ParentClass { // ... } @Entity @PrimaryKeyJoinColumn(name = "child2_id") public class Child2 extends ParentClass { // ... }
-
- DisAdvantage: Retrieving entities requires joins, between tables which can result in lower performance for large numbers of records.
-
Table per class:
- This strategy is similar to MappedSuperClass strategy. But it will indeed define entities for parent classes.
- DisAdvantage:
-
- when querying the base class, which will return all the subclass records as well by using a UNION statement in the background.
-
- The use of UNION can also lead to inferior performance when choosing this strategy. Another issue is that we can no longer use identity key generation.
# Joined Table
Hibernate: create table jt_employee (employee_id integer not null, salary float(53) not null, primary key (employee_id)) engine=InnoDB
Hibernate: create table jt_person (id integer not null, name varchar(255), primary key (id)) engine=InnoDB
Hibernate: create table jt_student (student_id integer not null, course varchar(255), primary key (student_id)) engine=InnoDB
Hibernate: alter table jt_employee add constraint FK555ns1r56eklon2eijvdcc3yd foreign key (employee_id) references jt_person (id)
Hibernate: alter table jt_student add constraint FK3uvwkb7c4ghu1jwi56lsl64t9 foreign key (student_id) references jt_person (id)
# MappedSuperClass
Hibernate: create table ms_employee (id integer not null, salary float(53) not null, name varchar(255), primary key (id)) engine=InnoDB
Hibernate: create table ms_student (id integer not null, course varchar(255), name varchar(255), primary key (id)) engine=InnoDB
# Single Table
Hibernate: create table st_person (id integer not null, salary float(53), person_type varchar(31) not null, course varchar(255), name varchar(255), primary key (id)) engine=InnoDB
# Table Per Class
Hibernate: create table tpc_employee (id integer not null, salary float(53) not null, name varchar(255), primary key (id)) engine=InnoDB
Hibernate: create table tpc_person (id integer not null, name varchar(255), primary key (id)) engine=InnoDB
Hibernate: create table tpc_student (id integer not null, course varchar(255), name varchar(255), primary key (id)) engine=InnoDB
- FetchType.LAZY
- FetchType.EAGER
@ManyToOne(fetch = FetchType.LAZY / EAGER)
public class ParentClass {
// ...
}