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.
Comments