JPA + Hibernate @Inheritance - JOINED Example

By Arvind Rai, February 27, 2023
On this page, we will learn to use JPA @Inheritance annotation with JOINED 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 JOINED inheritance strategy, the fields that are specific to a subclass are mapped to a separate table than the fields that are common to the parent class, and a join is performed to instantiate the subclass.
3. The @Inheritance annotation with JOINED strategy is specified at the root entity. The root entity persist data in parent table and subclass entity persist data in child table.
4. Parent table and child table are joined with foreign key and hence we need to specify @PrimaryKeyJoinColumn at subclass entity.
5. To use JOINED inheritance, we need to create a root class and some subclasses. Root class is annotated with @Entity and @Inheritance annotations.
@Entity(name = "account")
@Inheritance(strategy = InheritanceType.JOINED)
public class Account {
  ------
} 
6. Subclasses are annotated with @Entity and @PrimaryKeyJoinColumn annotations.
@Entity(name = "credit_account")
@PrimaryKeyJoinColumn(name = "ca_id")
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` (
	`ca_id` BIGINT(20) NOT NULL,
	`creditLimit` DECIMAL(19,2) NULL DEFAULT NULL,
	PRIMARY KEY (`ca_id`),
	CONSTRAINT `credit_account_ibfk_1` FOREIGN KEY (`ca_id`) REFERENCES `account` (`account_id`)
)
CREATE TABLE `debit_account` (
	`da_id` BIGINT(20) NOT NULL,
	`overdraftFee` DECIMAL(19,2) NULL DEFAULT NULL,
	PRIMARY KEY (`da_id`),
	CONSTRAINT `debit_account_ibfk_1` FOREIGN KEY (`da_id`) REFERENCES `account` (`account_id`)
) 

5. Java Code
Find the root class. Root class contains common fields for entity subclasses.
Account.java
@Entity(name = "account")
@Inheritance(strategy = InheritanceType.JOINED)
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
} 
CreditAccount.java
@Entity(name = "credit_account")
@PrimaryKeyJoinColumn(name = "ca_id")
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")
@PrimaryKeyJoinColumn(name = "da_id")
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();

	DebitAccount debitAccount = new DebitAccount(101L, BigDecimal.valueOf(150), BigDecimal.valueOf(1.2d), "Mahesh",
		BigDecimal.valueOf(50));
	CreditAccount creditAccount = new CreditAccount(202L, BigDecimal.valueOf(1500), BigDecimal.valueOf(1.6d), "Krishn",
		BigDecimal.valueOf(1000));

	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 debit_account (overdraftFee, da_id) values (?, ?)
Hibernate: insert into account (balance, interestRate, owner, account_id) values (?, ?, ?, ?)
Hibernate: insert into credit_account (creditLimit, ca_id) values (?, ?) 
Find the data inserted into database.
JPA + Hibernate @Inheritance - JOINED Example

References

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us