Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Criteria Queries

Hibernate's Criteria API provides a programmatic and type-safe way to create queries without using string-based HQL (Hibernate Query Language). It allows developers to build up a query using an object-oriented paradigm.

However, it's essential to note that the Criteria API was marked as deprecated in Hibernate 5.2 in favor of the JPA Criteria API. Still, for the sake of understanding and in case you're working with legacy code, let's delve into the traditional Hibernate Criteria API:

1. Basic Criteria Query

Let's start with a simple example where you want to retrieve all students from a Student table.

Session session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(Student.class);
List<Student> students = criteria.list();

2. Using Restrictions for Conditions

Restrictions is a utility class that provides methods to apply constraints, similar to SQL's WHERE clauses.

Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.eq("firstName", "John"));
List<Student> johns = criteria.list();

This will give you all students named John.

3. Logical Conditions

Criteria criteria = session.createCriteria(Student.class);
Criterion name = Restrictions.like("firstName", "John%");
Criterion age = Restrictions.gt("age", 20);
LogicalExpression or = Restrictions.or(name, age);
criteria.add(or);
List<Student> results = criteria.list();

The above query retrieves students named starting with "John" OR older than 20.

4. Projections & Aggregation

Criteria criteria = session.createCriteria(Student.class);
criteria.setProjection(Projections.rowCount());
int totalStudents = (int) criteria.uniqueResult();

The above code returns the total number of students.

5. Ordering Results

Criteria criteria = session.createCriteria(Student.class);
criteria.addOrder(Order.asc("age"));
List<Student> studentsOrderedByAge = criteria.list();

This returns all students ordered by age in ascending order.

6. Pagination

For pagination, you can use setFirstResult and setMaxResults:

Criteria criteria = session.createCriteria(Student.class);
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List<Student> firstTenStudents = criteria.list();

This fetches the first 10 students from the table.

7. Joining with Associations

Assuming Student has a OneToOne association with Profile:

Criteria criteria = session.createCriteria(Student.class)
    .createAlias("profile", "p")
    .add(Restrictions.eq("p.city", "New York"));
List<Student> studentsFromNY = criteria.list();

This fetches all students from New York.

Considerations:

  • Type-safety: One of the main disadvantages of the traditional Criteria API was its lack of type-safety. The JPA Criteria API improves on this by being more type-safe.

  • Deprecation: As mentioned earlier, this traditional Criteria API was deprecated in Hibernate 5.2, so for newer projects, it's recommended to use the JPA Criteria API or another querying technique.

  1. Dynamic queries with Hibernate Criteria:

    Hibernate Criteria is a powerful API for building dynamic queries in Hibernate without using HQL (Hibernate Query Language).

    Criteria criteria = session.createCriteria(Employee.class);
    criteria.add(Restrictions.eq("department", "IT"));
    criteria.add(Restrictions.gt("salary", 50000));
    List<Employee> result = criteria.list();
    
  2. Creating complex queries using Hibernate Criteria:

    Build complex queries by combining multiple criteria and conditions.

    Criteria criteria = session.createCriteria(Employee.class);
    Criterion salaryCriterion = Restrictions.gt("salary", 50000);
    Criterion departmentCriterion = Restrictions.eq("department", "IT");
    criteria.add(Restrictions.and(salaryCriterion, departmentCriterion));
    List<Employee> result = criteria.list();
    
  3. Hibernate Criteria query examples:

    Examples of using Hibernate Criteria for querying entities.

    Criteria criteria = session.createCriteria(Product.class);
    criteria.add(Restrictions.like("productName", "Laptop", MatchMode.ANYWHERE));
    criteria.addOrder(Order.desc("price"));
    List<Product> laptops = criteria.list();
    
  4. Criteria queries vs HQL in Hibernate:

    Compare Criteria queries and HQL to choose the appropriate approach based on the use case.

    • Criteria Query:

      Criteria criteria = session.createCriteria(Employee.class);
      criteria.add(Restrictions.eq("department", "IT"));
      List<Employee> result = criteria.list();
      
    • HQL Query:

      Query query = session.createQuery("FROM Employee WHERE department = :department");
      query.setParameter("department", "IT");
      List<Employee> result = query.list();
      
  5. Ordering and sorting with Hibernate Criteria:

    Use Order to specify the order of results in a Criteria query.

    Criteria criteria = session.createCriteria(Product.class);
    criteria.addOrder(Order.asc("productName"));
    List<Product> sortedProducts = criteria.list();
    
  6. Restrictions in Hibernate Criteria queries:

    Apply various restrictions using the Restrictions class in Hibernate Criteria.

    Criteria criteria = session.createCriteria(Employee.class);
    criteria.add(Restrictions.like("firstName", "John", MatchMode.START));
    criteria.add(Restrictions.between("salary", 50000, 80000));
    List<Employee> result = criteria.list();
    
  7. Projections in Hibernate Criteria API:

    Use projections to retrieve specific columns or aggregate functions.

    Criteria criteria = session.createCriteria(Employee.class);
    criteria.setProjection(Projections.property("firstName"));
    List<String> firstNames = criteria.list();
    
  8. Subqueries with Hibernate Criteria:

    Perform subqueries within a Criteria query for more complex scenarios.

    DetachedCriteria subquery = DetachedCriteria.forClass(Employee.class)
        .setProjection(Projections.avg("salary"));
    
    Criteria criteria = session.createCriteria(Employee.class);
    criteria.add(Property.forName("salary").gt(subquery));
    List<Employee> result = criteria.list();