JPA + Hibernate @Inheritance - TABLE_PER_CLASS

By Arvind Rai, March 01, 2023
On this page, we will learn to use JPA @Inheritance annotation with TABLE_PER_CLASS strategy in our Hibernate application.
1. The @Inheritance annotation specifies the inheritance strategy to be used for an entity class hierarchy. The inheritance strategy can be JOINED, SINGLE_TABLE and TABLE_PER_CLASS.
2. In TABLE_PER_CLASS inheritance strategy, we map only the concrete classes of an inheritance hierarchy to tables. Each table defines all persistent states of the class, including the inherited state.
3. The @Inheritance annotation with TABLE_PER_CLASS strategy is specified at the root entity. Root class and subclass entity persist data in separate tables mapped with them. Subclass entity contains the inherited fields and its own fields.
4. To use TABLE_PER_CLASS inheritance, we need to create a root class and some subclasses. Root class is annotated with @Entity and @Inheritance annotations. Root class persist data in a table mapped with it.
@Entity(name = "account")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Account {
------
} 
5. Subclasses persist data in the table mapped with them.
@Entity(name = "credit_account")
public class CreditAccount extends Account {
------
} 

Complete Example

1. Technologies Used
1. Java 19
2. Hibernate 6
3. Jakarta Persistence API 3
4. MySQL 5.5

2. pom.xml
<dependencies>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-core</artifactId>
		<version>6.1.6.Final</version>
	</dependency>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-entitymanager</artifactId>
		<version>6.0.0.Alpha7</version>
	</dependency>		
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>8.0.32</version>
	</dependency>
</dependencies> 
3. persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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="com.concretepage">
		<description>Procedure Demo</description>
		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
		<properties>
			<property name="hibernate.dialect"
				value="org.hibernate.dialect.MySQLDialect" />
			<property name="jakarta.persistence.jdbc.driver"
				value="com.mysql.cj.jdbc.Driver" />
			<property name="jakarta.persistence.jdbc.url"
				value="jdbc:mysql://localhost/concretepage" />
			<property name="jakarta.persistence.jdbc.user" value="root" />
			<property name="jakarta.persistence.jdbc.password"
				value="cp" />
			<property name="hibernate.show_sql" value="true" />
		</properties>
	</persistence-unit>
</persistence> 
4. MySQL Database
Find the tables.
CREATE TABLE `account` (
	`account_id` BIGINT(20) NOT NULL,
	`balance` DECIMAL(19,2) NULL DEFAULT NULL,
	`interestRate` DECIMAL(19,2) NULL DEFAULT NULL,
	`owner` VARCHAR(255) NULL DEFAULT NULL,
	PRIMARY KEY (`account_id`)
)
CREATE TABLE `credit_account` (
	`account_id` BIGINT(20) NOT NULL,
	`balance` DECIMAL(19,2) NULL DEFAULT NULL,
	`interestRate` DECIMAL(19,2) NULL DEFAULT NULL,
	`owner` VARCHAR(255) NULL DEFAULT NULL,
	`creditLimit` DECIMAL(19,2) NULL DEFAULT NULL,
	PRIMARY KEY (`account_id`)
)
CREATE TABLE `debit_account` (
	`account_id` BIGINT(20) NOT NULL,
	`balance` DECIMAL(19,2) NULL DEFAULT NULL,
	`interestRate` DECIMAL(19,2) NULL DEFAULT NULL,
	`owner` VARCHAR(255) NULL DEFAULT NULL,
	`overdraftFee` DECIMAL(19,2) NULL DEFAULT NULL,
	PRIMARY KEY (`account_id`)
) 

5. Java Code
Find the root class.
Account.java
@Entity(name = "account")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Account {
  @Id
  @Column(name = "account_id")
  private Long id;
  @Column(name = "balance")
  private BigDecimal balance;
  @Column(name = "interestRate")
  private BigDecimal interestRate;
  @Column(name = "owner")
  private String owner;

  public Account(Long id, BigDecimal balance, BigDecimal interestRate, String owner) {
	this.id = id;
	this.balance = balance;
	this.interestRate = interestRate;
	this.owner = owner;
  }
  // Setters and Getters
} 
Find the subclasses.
CreditAccount.java
@Entity(name = "credit_account")
public class CreditAccount extends Account {
  @Column(name = "creditLimit")
  private BigDecimal creditLimit;

  public CreditAccount(Long id, BigDecimal balance, BigDecimal interestRate, String owner, BigDecimal creditLimit) {
	super(id, balance, interestRate, owner);
	this.creditLimit = creditLimit;
  }
  // Setters and Getters
} 
DebitAccount.java
@Entity(name = "debit_account")
public class DebitAccount extends Account {
  @Column(name = "overdraftFee")
  private BigDecimal overdraftFee;

  public DebitAccount(Long id, BigDecimal balance, BigDecimal interestRate, String owner, BigDecimal overdraftFee) {
	super(id, balance, interestRate, owner);
	this.overdraftFee = overdraftFee;
  }
  // Setters and Getters
} 

Now run the code.
HibernateUtil.java
public class HibernateUtil {
 	private static final EntityManagerFactory emFactory;
	static {
		emFactory = Persistence.createEntityManagerFactory("com.concretepage");
	}
	public static EntityManager getEntityManager(){
		return emFactory.createEntityManager();
	}
} 
Main.java
public class Main {
  public static void main(String[] args) {
	EntityManager entityManager = HibernateUtil.getEntityManager();
	entityManager.getTransaction().begin();
	
        Account daccount = new Account(101L, BigDecimal.valueOf(150), BigDecimal.valueOf(1.2d), "Mahesh");
	DebitAccount debitAccount = new DebitAccount(101L, BigDecimal.valueOf(150), BigDecimal.valueOf(1.2d), "Mahesh",
		BigDecimal.valueOf(50));
	Account caccount = new Account(202L, BigDecimal.valueOf(1500), BigDecimal.valueOf(1.6d), "Krishn");
	CreditAccount creditAccount = new CreditAccount(202L, BigDecimal.valueOf(1500), BigDecimal.valueOf(1.6d), "Krishn",
		BigDecimal.valueOf(1000));
	
	entityManager.persist(daccount);
	entityManager.persist(caccount);
	entityManager.getTransaction().commit();
	entityManager.clear();
	entityManager.getTransaction().begin();
	entityManager.persist(debitAccount);	
	entityManager.persist(creditAccount);
	entityManager.getTransaction().commit();
	entityManager.close();
  }
} 
Output
Hibernate: insert into account (balance, interestRate, owner, account_id) values (?, ?, ?, ?)
Hibernate: insert into account (balance, interestRate, owner, account_id) values (?, ?, ?, ?)
Hibernate: insert into debit_account (balance, interestRate, owner, overdraftFee, account_id) values (?, ?, ?, ?, ?)
Hibernate: insert into credit_account (balance, interestRate, owner, creditLimit, account_id) values (?, ?, ?, ?, ?) 
Find the data inserted into database.
JPA + Hibernate @Inheritance - TABLE_PER_CLASS Example

References

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE







©2024 concretepage.com | Privacy Policy | Contact Us