Hibernate – Find All Records with HQL and Criteria API
Retrieving all records from a database table is one of the most fundamental operations in any application. Hibernate provides multiple ways to accomplish this: HQL (Hibernate Query Language), the Criteria API, and native SQL queries. This tutorial demonstrates how to set up Hibernate and fetch all records from a Product table using each approach.
Prerequisites
- Java 8 or later
- Hibernate 5.x or 6.x
- MySQL or any relational database
- Maven or Gradle project
Maven Dependencies
<dependencies>
<!-- Hibernate ORM -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.15.Final</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
hibernate.cfg.xml Configuration
<?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 = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name", nullable = false, length = 100)
private String name;
@Column(name = "price")
private double price;
@Column(name = "quantity")
private int quantity;
// Default constructor required by Hibernate
public Product() {}
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
// Getters
public int getId() { return id; }
public String getName() { return name; }
public double getPrice() { return price; }
public int getQuantity() { return quantity; }
@Override
public String toString() {
return String.format("Product{id=%d, name='%s', price=%.2f, qty=%d}",
id, name, price, quantity);
}
}
HibernateUtil – SessionFactory Helper
package com.java9r.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
return new Configuration().configure().buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
sessionFactory.close();
}
}
Find All Products – Three Approaches
package com.java9r;
import com.java9r.model.Product;
import com.java9r.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.query.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;
/**
* Hibernate – three ways to retrieve all records from a table.
*/
public class FindAllProducts {
public static void main(String[] args) {
// First, insert some test data
insertSampleData();
// Method 1: HQL (Hibernate Query Language)
findAllUsingHQL();
// Method 2: Criteria API
findAllUsingCriteria();
// Method 3: Native SQL
findAllUsingNativeSQL();
HibernateUtil.shutdown();
}
// -------------------------------------------------------
// Method 1: HQL – looks like SQL but uses class/field names
// -------------------------------------------------------
private static void findAllUsingHQL() {
System.out.println("\n=== Method 1: HQL ===");
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
// "Product" refers to the Java class name, not the table name
Query<Product> query = session.createQuery("FROM Product ORDER BY id", Product.class);
List<Product> products = query.list();
System.out.println("Found " + products.size() + " products:");
products.forEach(System.out::println);
}
}
// -------------------------------------------------------
// Method 2: Criteria API – type-safe, no string HQL
// -------------------------------------------------------
private static void findAllUsingCriteria() {
System.out.println("\n=== Method 2: Criteria API ===");
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).orderBy(cb.asc(root.get("price")));
List<Product> products = session.createQuery(cq).getResultList();
System.out.println("Found " + products.size() + " products (sorted by price):");
products.forEach(System.out::println);
}
}
// -------------------------------------------------------
// Method 3: Native SQL – use when you need database-specific SQL
// -------------------------------------------------------
@SuppressWarnings("unchecked")
private static void findAllUsingNativeSQL() {
System.out.println("\n=== Method 3: Native SQL ===");
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
List<Product> products = session
.createNativeQuery("SELECT * FROM products ORDER BY name", Product.class)
.getResultList();
System.out.println("Found " + products.size() + " products:");
products.forEach(System.out::println);
}
}
// Insert sample data for demonstration
private static void insertSampleData() {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
var tx = session.beginTransaction();
session.save(new Product("Laptop", 75000.00, 10));
session.save(new Product("Smartphone", 25000.00, 50));
session.save(new Product("Tablet", 35000.00, 30));
session.save(new Product("Monitor", 15000.00, 20));
session.save(new Product("Keyboard", 2500.00, 100));
tx.commit();
System.out.println("Sample data inserted.");
}
}
}
Expected Output
Sample data inserted.
=== Method 1: HQL ===
Found 5 products:
Product{id=1, name='Laptop', price=75000.00, qty=10}
Product{id=2, name='Smartphone', price=25000.00, qty=50}
Product{id=3, name='Tablet', price=35000.00, qty=30}
Product{id=4, name='Monitor', price=15000.00, qty=20}
Product{id=5, name='Keyboard', price=2500.00, qty=100}
=== Method 2: Criteria API ===
Found 5 products (sorted by price):
Product{id=5, name='Keyboard', price=2500.00, qty=100}
Product{id=4, name='Monitor', price=15000.00, qty=20}
Product{id=2, name='Smartphone', price=25000.00, qty=50}
Product{id=3, name='Tablet', price=35000.00, qty=30}
Product{id=1, name='Laptop', price=75000.00, qty=10}
=== Method 3: Native SQL ===
Found 5 products:
Product{id=5, name='Keyboard', price=2500.00, qty=100}
Product{id=1, name='Laptop', price=75000.00, qty=10}
Product{id=4, name='Monitor', price=15000.00, qty=20}
Product{id=2, name='Smartphone', price=25000.00, qty=50}
Product{id=3, name='Tablet', price=35000.00, qty=30}
HQL vs Criteria API vs Native SQL
| Approach | Type Safe? | Readable? | Database-specific? | Best For |
|---|---|---|---|---|
| HQL | No (strings) | Yes | No | Most queries |
| Criteria API | Yes | Verbose | No | Dynamic queries |
| Native SQL | No | Yes (SQL) | Yes | DB-specific features |
Summary
Hibernate offers three approaches to retrieve all records: HQL for its SQL-like readability, the Criteria API for compile-time type safety and dynamic query building, and native SQL when you need database-specific features. For simple "get all" queries, HQL is the cleanest option. Use the Criteria API when you build queries dynamically based on user input. Use native SQL only when HQL cannot express what you need. All three approaches work through Hibernate's session and benefit from connection pooling and caching.
Comments