📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
✅ Some premium posts are free to read — no account needed. Follow me on Medium to stay updated and support my writing.
🎓 Top 10 Udemy Courses (Huge Discount): Explore My Udemy Courses — Learn through real-time, project-based development.
▶️ Subscribe to My YouTube Channel (172K+ subscribers): Java Guides on YouTube
Note that when no explicit inheritance strategy is registered, Hibernate/JPA will choose the SINGLE_TABLE inheritance strategy by default.
SINGLE_TABLE inheritance performs the best in terms of executed SQL statements. However, you cannot use NOT NULL constraints on the column level. You can still use triggers and rules to enforce such constraints, but it’s not as straightforward.
Creating Models + Hibernate/JPA Mappings
Each subclass in a hierarchy must define a unique discriminator value, which is used to differentiate between rows belonging to separate subclass types. If this is not specified, the DTYPE column is used as a discriminator, storing the associated subclass name. The inheritance strategy is defined on the abstract superclass, using the @Inheritance annotation.Hibernate/JPA Single Table Inheritance Step-By-Step Example
Technologies and tools used
- Hibernate 6.1.7.Final
- IDE - Eclipse
- Maven 3.5.3
- JavaSE 17
- MySQL - 8.0.32
Development Steps
- Create a Simple Maven Project
- Project Directory Structure
- Add jar Dependencies to pom.xml
- Creating the JPA Entities
- Create a Hibernate configuration file - hibernate.cfg.xml
- Create a Hibernate utility class
- Create the Main class and Run an Application
1. Create a Simple Maven Project
Use the How to Create a Simple Maven Project in Eclipse article to create a simple Maven project in Eclipse IDE.2. Project Directory Structure
3. Add jar Dependencies to pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.javaguides.hibernate</groupId>
<artifactId>hibernate-tutorial</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>hibernate-singletable-example</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.7.Final</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
4. Creating the JPA Entities
Account.java
package net.javaguides.hibernate.entity;
import jakarta.persistence.*;
@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String owner;
private double balance;
private double interestRate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getInterestRate() {
return interestRate;
}
public void setInterestRate(double interestRate) {
this.interestRate = interestRate;
}
}
CreditAccount.java
package net.javaguides.hibernate.entity;
import jakarta.persistence.Entity;
@Entity(name = "CreditAccount")
public class CreditAccount extends Account {
private double creditLimit;
public double getCreditLimit() {
return creditLimit;
}
public void setCreditLimit(double creditLimit) {
this.creditLimit = creditLimit;
}
}
DebitAccount.java
package net.javaguides.hibernate.entity;
import jakarta.persistence.Entity;
@Entity(name = "DebitAccount")
public class DebitAccount extends Account {
private double overdraftFee;
public double getOverdraftFee() {
return overdraftFee;
}
public void setOverdraftFee(double overdraftFee) {
this.overdraftFee = overdraftFee;
}
}
5. Create a Hibernate configuration file - hibernate.cfg.xml
The configuration file contains information about the database and mapping file. Conventionally, its name should be hibernate.cfg.xml.Let's create an XML file named hibernate.cfg.xml under the /resources folder and write the following code in it.
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate_db?useSSL=false</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create-drop</property>
<!-- dbcp connection pool configuration -->
<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>
<mapping class="net.javaguides.hibernate.entity.CreditAccount" />
<mapping class="net.javaguides.hibernate.entity.DebitAccount" />
</session-factory>
</hibernate-configuration>
6. Create a Hibernate Utility Class
- Build the StandardServiceRegistry
- Build the Metadata
- Use those 2 to build the SessionFactory
package net.javaguides.hibernate.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
// Create registry
registry = new StandardServiceRegistryBuilder().configure().build();
// Create MetadataSources
MetadataSources sources = new MetadataSources(registry);
// Create Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return sessionFactory;
}
public static void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
7. Create the main App class and Run an Application
package net.javaguides.hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import net.javaguides.hibernate.entity.CreditAccount;
import net.javaguides.hibernate.entity.DebitAccount;
import net.javaguides.hibernate.util.HibernateUtil;
public class App {
public static void main(String[] args) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
// start a transaction
transaction = session.beginTransaction();
// save the account object
CreditAccount account = new CreditAccount();
account.setBalance(10000.0);
account.setInterestRate(10.0);
account.setOwner("Ramesh");
account.setCreditLimit(10000.0);
session.save(account);
DebitAccount debitAccount = new DebitAccount();
debitAccount.setBalance(10000.0);
debitAccount.setInterestRate(10.0);
debitAccount.setOwner("Ramesh");
debitAccount.setOverdraftFee(100.0);
session.persist(debitAccount);
// commit transaction
transaction.commit();
}
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
// start a transaction
Transaction transaction1 = session.beginTransaction();
// save the account object
CreditAccount creditAccount = session.get(CreditAccount.class, 1 L);
System.out.println(creditAccount.getBalance());
System.out.println(creditAccount.getId());
// commit transaction
transaction1.commit();
}
}
}
Comments
Post a Comment
Leave Comment