JPA Joined Table Strategy
@Inheritance(strategy = InheritanceType.JOINED)
Joind table strategy: In this inheritance strategy, tables are generated for all entities belonging to the relationship.
Let's follow the below steps in order to implement jpa joined table mechanism in your persistence entities.
As we create relationship among entites and achieve joined table strategy, thus let's imagaine we have 3 entity classes. Developer, Frontend, and Backend are our entity classes and Developer is the root entity in this relationship.
- Create the the root enttiy class called Developer with subsequent properties.
package com.company;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "developer")
@Inheritance(strategy = InheritanceType.JOINED)
public class Developer {
@Id
private int id;
private String name;
private int experience;
public Developer() {
}
public Developer(int id, String name, int experience) {
this.id = id;
this.name = name;
this.experience = experience;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getExperience() {
return experience;
}
public void setExperience(int experience) {
this.experience = experience;
}
}
- Then, create FrontendDeveloper entity class with the following properties. As the FrontendDeveloper is the subclass of Developer entity class, so it will inherit all the properties of Develpoer class behind the scene.
package com.company;
import jakarta.persistence.Entity;
@Entity
public class FrontendDeveloper extends Developer {
private int salary;
public FrontendDeveloper(){
super();
}
public FrontendDeveloper(int salary) {
this.salary = salary;
}
public FrontendDeveloper(int id, String name, int experience, String genre, int salary) {
super(id, name, experience);
this.salary = salary;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
}
Here you can see, this enity doesn't have it's own primary key, that means it's a child entity.
- Create another entity class called BackendDeveloper in com.company package. It also contains salary, bonus as propeties and it will extend the Developer enity as well. And it doesn't have primary key or id like FrontendDeveloper.
package com.company;
import jakarta.persistence.Entity;
@Entity
public class BackendDeveloper extends Developer {
private int salary;
private int bonus;
public BackendDeveloper() {
super();
}
public BackendDeveloper(int salary, int bonus) {
this.salary = salary;
this.bonus = bonus;
}
public BackendDeveloper(int id, String name, int experience, int salary, int bonus) {
super(id, name, experience);
this.salary = salary;
this.bonus = bonus;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
}
Here, we have extra property int bonus in the BackendDeveloper class.
- Now create persistence.xml file under src/main/resources/META-INF folder. And map the entity classess and database information details there.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name ="default">
<class>com.company.Developer</class>
<class>com.company.FrontendDeveloper</class>
<class>com.company.BackendDeveloper</class>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testdb"/>
<property name="jakarta.persistence.jdbc.user" value="root"/>
<property name="jakarta.persistence.jdbc.password" value="root"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Here, persistence-unit name is "default" that we will refer in the persistent class.
- Now create Persistent.java class in com.company package. In this class we will create entity objects and persist or save them to our mysql relational database.
package com.company;
import com.company.*;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
public class Persistent {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
EntityManager em =emf.createEntityManager();
em.getTransaction().begin();
FrontendDeveloper fd1 = new FrontendDeveloper(101, "Zakir Hossain", 2, 800);
FrontendDeveloper fd2 = new FrontendDeveloper(102, "Vlad Smith", 4, 1200);
BackendDeveloper bd1 = new BackendDeveloper(104, "Abdul Wahed", 5, 2000, 500);
BackendDeveloper bd2 = new BackendDeveloper(104, "Shakil Ahmed", 3, 1500, 200);
em.persist(fd1);
em.persist(fd2);
em.persist(bd1);
em.persist(bd2);
em.getTransaction().commit();
em.close();
emf.close();
}
}
- After executing the Persistent.java class, open your mysql workbench and you see 3 tables will be generated per entity class.
If we run: select * from developer; We get the following output.
mysql> select * from developer;
+-----+------------+---------------+
| id | experience | name |
+-----+------------+---------------+
| 101 | 2 | Zakir Hossain |
| 102 | 4 | Vlad Smith |
| 104 | 5 | Abdul Wahed |
| 105 | 3 | Shakil Ahmed |
+-----+------------+---------------+
4 rows in set (0.00 sec)
mysql>
If we run: select * from frontend_developer; We get the following output.
mysql> select * from frontend_developer;
+--------+-----+
| salary | id |
+--------+-----+
| 800 | 101 |
| 1200 | 102 |
+--------+-----+
2 rows in set (0.00 sec)
mysql>
If we run: select * from backend_developer; We get the following output.
mysql> select * from backenddeveloper;
+-------+--------+-----+
| bonus | salary | id |
+-------+--------+-----+
| 500 | 2000 | 104 |
| 200 | 1500 | 105 |
+-------+--------+-----+
2 rows in set (0.00 sec)
mysql>
Note: You might get error, if you already have tables with the same name, if not production based, you can delete those tables and rerun the application or please change the tables name regarding this relationship.
Talk soon, Shakil Ahmed.