Hibernate Java

Hibernate – Find a Record by ID

Hibernate – Find a Record by ID

Fetching a single record by its primary key is the most common database read operation. Hibernate provides two methods for this: session.get() and session.load(). They behave differently, and choosing the right one matters. This tutorial demonstrates both with a complete working example.

Prerequisites

  • Java 8 or later
  • Hibernate 5.x
  • MySQL database
  • Maven project

Database Table

CREATE TABLE product (
  id          INT          NOT NULL AUTO_INCREMENT,
  name        VARCHAR(45)  DEFAULT NULL,
  price       DECIMAL(10,0) DEFAULT NULL,
  quantity    INT          DEFAULT NULL,
  description VARCHAR(450) DEFAULT NULL,
  active      TINYINT(1)   DEFAULT NULL,
  created_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

hibernate.cfg.xml

<?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="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/java9rdb</property>
    <property name="connection.username">root</property>
    <property name="connection.password">yourpassword</property>
    <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>
    <mapping class="com.java9r.model.Product"/>
  </session-factory>
</hibernate-configuration>

Product Entity

package com.java9r.model;

import javax.persistence.*;

@Entity
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name", length = 45)
    private String name;

    @Column(name = "price")
    private Long price;

    @Column(name = "quantity")
    private Integer quantity;

    @Column(name = "description", length = 450)
    private String description;

    @Column(name = "active")
    private Boolean active;

    public Product() {}

    public Integer getId()          { return id; }
    public String  getName()        { return name; }
    public Long    getPrice()       { return price; }
    public Integer getQuantity()    { return quantity; }
    public String  getDescription() { return description; }
    public Boolean getActive()      { return active; }

    @Override
    public String toString() {
        return String.format("Product{id=%d, name='%s', price=%d, qty=%d, active=%s}",
                             id, name, price, quantity, active);
    }
}

HibernateUtil

package com.java9r.util;

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

public class HibernateUtil {

    private static final SessionFactory sessionFactory =
            new Configuration().configure().buildSessionFactory();

    public static SessionFactory getSessionFactory() { return sessionFactory; }
    public static void shutdown()                    { sessionFactory.close(); }
}

ProductDAO – Find by ID

package com.java9r.dao;

import com.java9r.model.Product;
import com.java9r.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.query.Query;

import javax.persistence.criteria.*;
import java.util.List;

public class ProductDAO {

    // ------------------------------------------------------------------
    // Method 1: session.get() — hits the database immediately,
    // returns null if not found. Recommended for most use cases.
    // ------------------------------------------------------------------
    public Product findById(Integer id) {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            Product product = session.get(Product.class, id);
            if (product == null) {
                System.out.println("No product found with id: " + id);
            }
            return product;
        }
    }

    // ------------------------------------------------------------------
    // Method 2: HQL query — useful when filtering by non-PK fields
    // ------------------------------------------------------------------
    public Product findByIdHQL(Integer id) {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            Query<Product> query = session.createQuery(
                "FROM Product WHERE id = :id", Product.class);
            query.setParameter("id", id);
            return query.uniqueResult();   // null if not found
        }
    }

    // ------------------------------------------------------------------
    // Method 3: Criteria API — type-safe, useful in dynamic query builders
    // ------------------------------------------------------------------
    public Product findByIdCriteria(Integer id) {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            CriteriaBuilder cb = session.getCriteriaBuilder();
            CriteriaQuery<Product> cq = cb.createQuery(Product.class);
            Root<Product> root = cq.from(Product.class);
            cq.select(root).where(cb.equal(root.get("id"), id));
            List<Product> results = session.createQuery(cq).getResultList();
            return results.isEmpty() ? null : results.get(0);
        }
    }
}

Main Class

package com.java9r;

import com.java9r.dao.ProductDAO;
import com.java9r.model.Product;
import com.java9r.util.HibernateUtil;

public class FindProductMain {

    public static void main(String[] args) {
        ProductDAO dao = new ProductDAO();

        // Method 1: session.get()
        System.out.println("=== Method 1: session.get() ===");
        Product p1 = dao.findById(2);
        if (p1 != null) {
            System.out.println("Id:          " + p1.getId());
            System.out.println("Name:        " + p1.getName());
            System.out.println("Price:       " + p1.getPrice());
            System.out.println("Quantity:    " + p1.getQuantity());
            System.out.println("Description: " + p1.getDescription());
            System.out.println("Active:      " + p1.getActive());
        }

        // Method 2: HQL
        System.out.println("\n=== Method 2: HQL ===");
        Product p2 = dao.findByIdHQL(2);
        System.out.println(p2);

        // Method 3: Criteria API
        System.out.println("\n=== Method 3: Criteria API ===");
        Product p3 = dao.findByIdCriteria(2);
        System.out.println(p3);

        // Test with non-existent ID
        System.out.println("\n=== Non-existent ID (999) ===");
        Product p4 = dao.findById(999);
        System.out.println("Result: " + p4);

        HibernateUtil.shutdown();
    }
}

Expected Output

=== Method 1: session.get() ===
Hibernate: select ... from product where id=?
Id:          2
Name:        Smartphone
Price:       25000
Quantity:    50
Description: Latest flagship smartphone
Active:      true

=== Method 2: HQL ===
Hibernate: select ... from product where id=?
Product{id=2, name='Smartphone', price=25000, qty=50, active=true}

=== Method 3: Criteria API ===
Hibernate: select ... from product where id=?
Product{id=2, name='Smartphone', price=25000, qty=50, active=true}

=== Non-existent ID (999) ===
No product found with id: 999
Result: null

get() vs load() – Key Difference

Aspect session.get() session.load()
Database hit Immediate SELECT Returns a proxy; SELECT on first field access
Not found behavior Returns null Throws ObjectNotFoundException on access
Use when You're not sure the record exists You're certain it exists and want lazy loading
Recommended? Yes — safe default Only for association loading inside open sessions

Summary

Use session.get(Class, id) as the default way to fetch a single record by primary key — it hits the database immediately and returns null if the record is not found, making null-checks straightforward. Use HQL (FROM Product WHERE id = :id) when you want to filter by conditions or select specific columns. Use the Criteria API when you need a type-safe, programmatically built query. Avoid session.load() unless you have a specific reason to defer the SELECT until the entity's fields are accessed.

Topics: Hibernate Java
← Newer Post Older Post →

Comments

https://www.blogger.com/comment/frame/6690124484600543990?po=5501693104120958720&hl=en&saa=85391&origin=https://www.java9r.com