Open In App

JPA Table-per-class Strategy

Last Updated : 23 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Table-Per-class strategy in JPA is one of the inheritance mapping strategies used to map inheritance hierarchies to the database table. This strategy can map each class in the inheritance to its database table of the application.

The Table-per-class strategy can involve creating a separate table for each class in the inheritance hierarchy. It means that all the properties of each class are stored in the corresponding table and it can include the inherited properties.

Implementation Steps of Table-per-class Strategy

Below are the steps to implement a Table-per-class Strategy in JPA.

1. Define the Entity class

We can define the entity class representing the inheritance hierarchy of the application.

For Example: Vehicle Entity

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String manufacturer;
// Other properties and methods
}

Car Subclass:

@Entity
public class Car extends Vehicle {
private int numberOfDoors;
// Other properties and methods
}

Bike Subclass:

@Entity
public class Bike extends Vehicle {
private boolean hasBasket;
// Other properties and methods
}

2. Generate the Tables

We can generates the createEntityManagerFactory method along with the property of the hibernate.hdm2ddl.auto set to the update

 public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("examplePU");
EntityManager em = emf.createEntityManager();

em.getTransaction().begin();

// Create instances of vehicles
Car car = new Car();
car.setManufacturer("Toyota");
car.setNumberOfDoors(4);

Bike bike = new Bike();
bike.setManufacturer("Honda");
bike.setHasBasket(true);

// Persist the vehicles
em.persist(car);
em.persist(bike);

em.getTransaction().commit();

em.close();
emf.close();
}

Single Table Inheritance:

  • In this approach, we can define all the properties of all subclasses are stored in the single table.
  • Requires the use of the discriminator columns to the differentiate between the subclasses and it can lead to the large numbers of the null values in the table.

Joined Table Inheritance:

  • We can define each class in the hierarchy is mapped to its own table.
  • Subclass tables can have the foreign key relationships with the superclass tables of the application.
  • Results in the normalized database schema but requires the join for quering.

Mapped Superclass:

  • Used when the inheritance is implemented without the entity inheritance of the application.
  • Common fields are defined in the separate the class(superclass) and subclasses inherit these fields.
  • Subclasses are not the entities and they cannot be the queried directly of the application.

Project Implementation of the Table-per-class Strategy in JPA

Step 1: First, we will implement JPA using Intellij Idea IDE. The project named as jpa-table-per-strategy-demo.

Step 2: Next, we will add the following dependencies to the created JPA project.

Dependencies:

<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.2</version>
</dependency>


The project layout then looks like the image below:


Folder Structure


Step 3: Now, open the persistence.xml file and write the below code for the MYSQL database structure of the database.

XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
  <persistence-unit name="TablePerClassPU">
    <class>model.Car</class>
    <class>model.Bike</class>
    <class>model.Vehicle</class>

    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/example"/>
      <property name="javax.persistence.jdbc.user" value="root"/>
      <property name="javax.persistence.jdbc.password" value=""/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>


Step 4: After all the above steps, now create a package called model and inside that package create an entity class called Vehicle.

Go to src > main > java > model > Vehicle and write the below code file..

Java
package model;

import jakarta.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;

    private String manufacturer;

    // Getters and Setters

    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;
    }
}


Step 5: Now create a package named model and inside that package create an entity class named Car.

Go to src > main > java > model > Car and write the below code file..

Java
package model;

import jakarta.persistence.Entity;

@Entity
public class Car extends Vehicle {
    private int numberOfDoors;

    // Getters and Setters


    public int getNumberOfDoors() {
        return numberOfDoors;
    }

    public void setNumberOfDoors(int numberOfDoors) {
        this.numberOfDoors = numberOfDoors;
    }
}


Step 6: After all the above steps then create a package named model and inside that package create an entity class named Bike.

Go to src > main > java > model > Bike and write the below code file..

Java
package model;

import jakarta.persistence.Entity;

@Entity
public class Bike extends Vehicle {
    private boolean hasBasket;

    // Getters and Setters
  
    public boolean isHasBasket() {
        return hasBasket;
    }

    public void setHasBasket(boolean hasBasket) {
        this.hasBasket = hasBasket;
    }
}


Step 7: Create a new Java class and name it MainApplication.

Go to src > main > java > MainApplication and write the below code.

Java
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;
import model.Bike;
import model.Car;

public class MainApplication {
    public static void main(String[] args) {
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("TablePerClassPU");
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();

        // Persisting entities
        transaction.begin();

        Car car = new Car();
        car.setManufacturer("Toyota");
        car.setNumberOfDoors(4);

        Bike bike = new Bike();
        bike.setManufacturer("Honda");
        bike.setHasBasket(true);

        entityManager.persist(car);
        entityManager.persist(bike);

        transaction.commit();

        // Retrieving entities
        Car retrievedCar = entityManager.find(Car.class, car.getId());
        System.out.println("Retrieved Car: " + retrievedCar.getManufacturer());

        Bike retrievedBike = entityManager.find(Bike.class, bike.getId());
        System.out.println("Retrieved Bike: " + retrievedBike.getManufacturer());

        entityManager.close();
        entityManagerFactory.close();
    }
}
  • The above file demonstrates the use of the Table-per-class inheritance strategy in JPA.
  • It creates instances of Car and Bike entities, persists them to the database, retrieves them, and prints their manufacturer details to the console.
  • Finally, it closes the entity manager and entity manager factory.


pom.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>jpa-table-per-strategy-demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>jpa-table-per-strategy-demo</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <junit.version>5.9.2</junit.version>
  </properties>

  <dependencies>
     <dependency>
      <groupId>org.hibernate.orm</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>6.0.2.Final</version>
    </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.28</version>
      </dependency>
    <dependency>
      <groupId>org.glassfish.jaxb</groupId>
      <artifactId>jaxb-runtime</artifactId>
      <version>3.0.2</version>
    </dependency>
<dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
      <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
      </dependency>  </dependencies>

  <build>
    <plugins>
    </plugins>
  </build>
</project>


Step 8: Once the process is done, run the application and we will get output like the image below.

Application Runs

In the above example, we can demonstrate how to use the Table-per-class strategy to the map inheritance hierarchies to the databases using JPA in the JPA application.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads