Define Unique Key in JPA/Hibernate Entity

🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.

▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube

▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube

In this tutorial, we will demonstrate how to define a unique key in a JPA/Hibernate entity. A unique key ensures that the specified columns contain unique values, preventing duplicate entries.

We will create a simple Hibernate Maven project to demonstrate how to define a unique key in a JPA entity. Note that Hibernate is a popular JPA provider.

Prerequisites

  1. Java Development Kit (JDK) 21 or higher: Ensure JDK is installed and configured in your system.
  2. Integrated Development Environment (IDE): IntelliJ IDEA, Eclipse, or any other IDE.
  3. Maven: Ensure Maven is installed and configured in your system.

Step 1: Create a Maven Project

  1. Open your IDE and create a new Maven project.
  2. Update the pom.xml file to include Hibernate and other required dependencies.
<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>
    <groupId>com.example</groupId>
    <artifactId>hibernate-unique-key-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.2.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
        </dependency>
    </dependencies>
</project>

Explanation

  • Hibernate Core Dependency: This includes the main Hibernate framework, which implements JPA.
  • SLF4J Dependencies: Used for logging.
  • H2 Database Dependency: An in-memory database for testing purposes.

Step 2: Create Hibernate Configuration File

Create a file named hibernate.cfg.xml in the src/main/resources directory.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:testdb</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
    </session-factory>
</hibernate-configuration>

Explanation

  • Dialect: Specifies the SQL dialect (H2 in this case).
  • Connection Properties: Configure the JDBC connection to the H2 database.
  • hbm2ddl.auto: Automatically manages the database schema (update existing schema).
  • show_sql: Prints SQL statements to the console.
  • format_sql: Formats SQL statements.

Step 3: Create the Employee Entity Class with a Unique Key

Create a package named com.example.entity and a class named Employee.

package com.example.entity;

import jakarta.persistence.*;

@Entity
@Table(name = "Employee", uniqueConstraints = {@UniqueConstraint(columnNames = "email")})
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column(nullable = false, unique = true)
    private String email;

    public Employee() {}

    public Employee(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + '\'' + ", email='" + email + '\'' + '}';
    }
}

Explanation

  • @Table: Specifies the table details and unique constraints.
  • @UniqueConstraint: Defines unique constraints on the table level.
  • @Column: Marks the email column as unique.

Step 4: Create Hibernate Utility Class

Create a package named com.example.util and a class named HibernateUtil.

package com.example.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {
    private static SessionFactory sessionFactory;

    static {
        try {
            Configuration configuration = new Configuration().configure();
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties()).build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Explanation

  • Configuration: Loads Hibernate configuration from hibernate.cfg.xml.
  • ServiceRegistry: Builds the service registry from the configuration settings.
  • SessionFactory: Provides sessions to interact with the database.

Step 5: Create Main Class

Create a package named com.example and a class named Main.

package com.example;

import com.example.entity.Employee;
import com.example.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Main {
    public static void main(String[] args) {
        // Save a new employee
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = session.beginTransaction();
        Employee employee1 = new Employee("John Doe", "john.doe@example.com");
        session.save(employee1);
        transaction.commit();
        session.close();

        // Try to save another employee with the same email
        session = HibernateUtil.getSessionFactory().openSession();
        transaction = session.beginTransaction();
        try {
            Employee employee2 = new Employee("Jane Doe", "john.doe@example.com");
            session.save(employee2);
            transaction.commit();
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            transaction.rollback();
        } finally {
            session.close();
        }

        // Retrieve and display the employee
        session = HibernateUtil.getSessionFactory().openSession();
        Employee retrievedEmployee = session.get(Employee.class, employee1.getId());
        System.out.println("Retrieved Employee: " + retrievedEmployee);

        // Close the SessionFactory
        HibernateUtil.getSessionFactory().close();
    }
}

Explanation

  • Session: Opens a session to interact with the database.
  • Transaction: Begins and commits a transaction for database operations.
  • Save: Persists the entity to the database.
  • Try-Catch Block: Demonstrates handling of unique constraint violation.

Step 6: Run the Application

  1. Run the Main class.
  2. The output in the console should be:
Hibernate: create table Employee (id bigint generated by default as identity, email varchar(255) not null, name varchar(255), primary key (id), unique (email))
Hibernate: insert into Employee (email, name) values (?, ?)
Hibernate: select employee0_.id as id1_0_0_, employee0_.email as email2_0_0_, employee0_.name as name3_0_0_ from Employee employee0_ where employee0_.id=?
Retrieved Employee: Employee{id=1, name='John Doe', email='john.doe@example.com'}

Conclusion

You have successfully created an example using Hibernate to define a unique key in a JPA/Hibernate entity. This tutorial covered setting up a Maven project, configuring Hibernate, creating an entity class with unique constraints, and handling unique constraint violations during CRUD operations.

My Top and Bestseller Udemy Courses. The sale is going on with a 70 - 80% discount. The discount coupon has been added to each course below:

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare