The Criteria API is an alternative to HQL (Hibernate Query Language ) for writing dynamic queries in Hibernate. Instead of writing queries as plain strings , Criteria API allows type-safe, object-oriented queries .
Why Use Criteria API? โ
Dynamic Queries โ Queries can be built at runtime.
โ
Type-Safe โ Uses Java classes instead of raw strings.
โ
No String-Based HQL โ Avoids syntax errors from misspelled query strings.
โ
Better Maintainability โ Queries are constructed programmatically.
Setting Up Criteria API To use Criteria API , you need to get a Session and use the CriteriaBuilder class.
HibernateUtil.java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
return new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Person.class)
.addAnnotatedClass(Course.class)
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("SessionFactory creation failed: " + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() {
return sessionFactory.openSession(); // Opens a new session when needed
}
public static void shutdown() {
sessionFactory.close(); // Close SessionFactory when the application shuts down
}
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Session session = HibernateUtil.getSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Fetch All Records (Equivalent to SELECT * FROM table ):
Session session = HibernateUtil.getSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Student.class);
Root root = query.from(Student.class);
query.select(root);
List students = session.createQuery(query).getResultList();
System.out.println(students);
session.close();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Applying WHERE Condition ๐น Fetch Students with Age > 20
๐น Equivalent SQL: SELECT * FROM student WHERE age > 20;
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Student.class);
Root root = query.from(Student.class);
query.select(root).where(builder.gt(root.get("age"), 20));
List students = session.createQuery(query).getResultList();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Applying Multiple Conditions ( AND , OR ) ๐น Fetch Students where age > 20 AND name starts with 'A'
๐น Equivalent SQL: SELECT * FROM student WHERE age > 20 AND name LIKE 'A%';
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Student.class);
Root root = query.from(Student.class);
Predicate agePredicate = builder.gt(root.get("age"), 20);
Predicate namePredicate = builder.like(root.get("name"), "A%");
query.select(root).where(builder.and(agePredicate, namePredicate));
List students = session.createQuery(query).getResultList();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Sorting Results ( ORDER BY ) ๐น Sort Students by Age (Ascending)
๐น Equivalent SQL: SELECT * FROM student ORDER BY age ASC;
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Student.class);
Root root = query.from(Student.class);
query.select(root).orderBy(builder.asc(root.get("age")));
List students = session.createQuery(query).getResultList();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
๐น Sort Students by Name (Descending)
๐น Equivalent SQL: SELECT * FROM student ORDER BY name DESC;
query.orderBy(builder.desc(root.get("name")));
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Fetching Specific Columns ๐น Select Only Name and Age
๐น Equivalent SQL: SELECT name, age FROM student;
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Object[].class);
Root root = query.from(Student.class);
query.multiselect(root.get("name"), root.get("age"));
List results = session.createQuery(query).getResultList();
for (Object[] row : results) {
System.out.println("Name: " + row[0] + ", Age: " + row[1]);
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Aggregation Functions (COUNT, SUM, AVG, MIN, MAX) ๐น Count Total Students
๐น Equivalent SQL: SELECT COUNT(*) FROM student;
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Long.class);
Root root = query.from(Student.class);
query.select(builder.count(root));
Long count = session.createQuery(query).getSingleResult();
System.out.println("Total Students: " + count);
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
๐น Find Average Age
๐น Equivalent SQL: SELECT AVG(age) FROM student;
query.select(builder.avg(root.get("age")));
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Using Joins in Criteria API ๐น Inner Join (Fetch Students with their Courses)
๐น Equivalent SQL: SELECT * FROM student JOIN course ON student.id = course.student_id;
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(Student.class);
Root root = query.from(Student.class);
Join courseJoin = root.join("courses"); // Assuming 'courses' is a List
query.select(root);
List students = session.createQuery(query).getResultList();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
๐น Left Join (Fetch Students Even If They Have No Courses)
๐น Equivalent SQL: SELECT * FROM student LEFT JOIN course ON student.id = course.student_id;
Join courseJoin = root.join("courses", JoinType.LEFT);
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Pagination (Limit & Offset) Hibernate Criteria API allows pagination using setFirstResult() and setMaxResults() .
๐น Fetch Page 2 (5 Records Per Page)
๐น Equivalent SQL: SELECT * FROM student LIMIT 5 OFFSET 5;
List students = session.createQuery(query)
.setFirstResult(5) // Skip first 5 records (Page 2)
.setMaxResults(5) // Fetch next 5 records
.getResultList();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Deleting Data using Criteria API ๐น Equivalent SQL: DELETE FROM student WHERE name = 'John';
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaDelete deleteQuery = builder.createCriteriaDelete(Student.class);
Root root = deleteQuery.from(Student.class);
deleteQuery.where(builder.equal(root.get("name"), "John"));
session.beginTransaction();
int deletedCount = session.createQuery(deleteQuery).executeUpdate();
session.getTransaction().commit();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Updating Data using Criteria API ๐น Equivalent SQL: UPDATE student SET age = 25 WHERE name = 'Alice';
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaUpdate updateQuery = builder.createCriteriaUpdate(Student.class);
Root root = updateQuery.from(Student.class);
updateQuery.set("age", 25).where(builder.equal(root.get("name"), "Alice"));
session.beginTransaction();
int updatedCount = session.createQuery(updateQuery).executeUpdate();
session.getTransaction().commit();
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">