Installing and Setting Up Hibernate: A Step-by-Step Guide for Java Developers

Illustration for Installing and Setting Up Hibernate: A Step-by-Step Guide for Java Developers
By Last updated:

When working with databases in Java, developers often struggle with repetitive JDBC boilerplate code and SQL statements. Hibernate, a powerful Object-Relational Mapping (ORM) framework, eliminates much of this burden by allowing you to work with Java objects instead of raw SQL.

In this tutorial, we’ll walk through the step-by-step process of installing and setting up Hibernate, from adding dependencies to writing your first CRUD operations. Whether you’re a beginner setting up Hibernate for the first time or an advanced developer refreshing your knowledge, this guide covers everything you need.


Step 1: Add Hibernate Dependency

The easiest way to include Hibernate is with Maven.

Maven Dependency

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.4.1.Final</version>
</dependency>

If you use Gradle, add:

implementation 'org.hibernate.orm:hibernate-core:6.4.1.Final'

Step 2: Configure Database Connection

Hibernate requires a configuration file to connect to your database.

hibernate.cfg.xml

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.show_sql">true</property>
  </session-factory>
</hibernate-configuration>

Key property:

  • hibernate.hbm2ddl.auto=update → auto creates/updates tables based on entity mappings.

Step 3: Create Entity Class

Entities map Java objects to database tables.

import jakarta.persistence.*;

@Entity
@Table(name = "students")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "student_name", nullable = false)
    private String name;

    public Student() {}

    public Student(String name) {
        this.name = name;
    }

    // Getters and setters
}

Common Annotations

  • @Entity → Declares class as an entity.
  • @Table → Maps to DB table.
  • @Id → Primary key.
  • @GeneratedValue → Auto ID generation.

Step 4: Build SessionFactory

SessionFactory is the core of Hibernate.

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new Configuration()
                    .configure("hibernate.cfg.xml")
                    .addAnnotatedClass(Student.class)
                    .buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

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

Step 5: Perform CRUD Operations

Create (Insert)

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();

Student student = new Student("Alice");
session.persist(student);

tx.commit();
session.close();

Read (Select)

Session session = HibernateUtil.getSessionFactory().openSession();
Student student = session.get(Student.class, 1L);
System.out.println(student.getName());
session.close();

Update

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();

Student student = session.get(Student.class, 1L);
student.setName("Updated Alice");
session.update(student);

tx.commit();
session.close();

Delete

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();

Student student = session.get(Student.class, 1L);
session.remove(student);

tx.commit();
session.close();

Step 6: Querying with Hibernate

HQL (Hibernate Query Language)

List<Student> students = session.createQuery("FROM Student WHERE name = :name", Student.class)
        .setParameter("name", "Alice")
        .list();

Criteria API

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> root = cq.from(Student.class);
cq.select(root).where(cb.equal(root.get("name"), "Alice"));
List<Student> students = session.createQuery(cq).getResultList();

Native SQL

List<Object[]> results = session.createNativeQuery("SELECT * FROM students").list();

Step 7: Enable Caching and Fetching Strategies

  • Lazy Loading (default) → Fetch data only when needed (like ordering food when hungry).
  • Eager Loading → Fetch everything immediately (like ordering all dishes at once).
  • First-Level Cache → Session-specific, enabled by default.
  • Second-Level Cache → Application-wide, using EHCache or Infinispan.

Step 8: Real-World Integration (Spring Boot)

Spring Boot simplifies Hibernate setup.

spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

Repository:

public interface StudentRepository extends JpaRepository<Student, Long> {}

Common Pitfalls

  • N+1 Select Problem → Too many queries, fix with JOIN FETCH.
  • Cascade Misuse → Wrong cascade config can delete unintended data.
  • Overusing Eager Fetching → Performance degradation.

Best Practices

  • Use lazy fetching by default.
  • Use DTOs for API responses.
  • Profile queries with Hibernate statistics.
  • Tune batch fetching and caching for performance.

📌 Hibernate Version Notes

Hibernate 5.x

  • Uses javax.persistence.
  • Legacy configuration style.
  • Older Criteria API.

Hibernate 6.x

  • Migrated to jakarta.persistence.
  • Enhanced SQL and query API.
  • Modern bootstrapping support.

Conclusion and Key Takeaways

  • Hibernate setup requires dependency, configuration, entities, and SessionFactory.
  • CRUD operations are streamlined with Hibernate Sessions.
  • Queries can be written using HQL, Criteria API, or native SQL.
  • Proper fetching and caching improve performance.
  • Hibernate integrates smoothly with Spring Boot for enterprise apps.

FAQ: Expert Hibernate Questions

  1. What’s the difference between Hibernate and JPA?
    JPA is a specification; Hibernate is a popular implementation.

  2. How does Hibernate caching improve performance?
    By reducing repeated database queries through session and second-level cache.

  3. What are the drawbacks of eager fetching?
    Loads unnecessary data, impacting speed and memory.

  4. How do I solve the N+1 select problem in Hibernate?
    Use JOIN FETCH or batch fetching strategies.

  5. Can I use Hibernate without Spring?
    Yes, Hibernate runs standalone with configuration files.

  6. What’s the best inheritance mapping strategy?
    Use JOINED for normalization, SINGLE_TABLE for speed.

  7. How does Hibernate handle composite keys?
    Using @EmbeddedId or @IdClass.

  8. How is Hibernate 6 different from Hibernate 5?
    Hibernate 6 uses jakarta.persistence and supports enhanced SQL APIs.

  9. Is Hibernate good for microservices?
    Yes, but lightweight DTOs and stateless design are recommended.

  10. When should I not use Hibernate?
    Avoid in performance-critical analytics or batch-processing apps.