How to use criteria api in Hibernate / Using criteria to fetch records in Hibernate

What is Criteria api?
Criteria api in Hibernate is used to fetch data from database tables. Though Hibernate Query Language can also be used to perform the same task but using queries makes maintenance difficult since the queries need to be written in string format while using Criteria involves classes and their properties. It should be noted that Criteria can only be used to fetch data(or SELECT operations) and not for data manipulation tasks such as Insert, Update or Delete.

With Criteria api, you can
1. Fetch all records from a table(all columns and rows).
2. Fetch only selected columns.
3. Fetch records matching some condition(such as a website with name ‘codippa’)
4. Apply sorting on the records while fetching.
5. Apply JOINS for fetching records from multiple tables.
This post will guide you through the method of creating a criteria and use it to fetch records.


Database table and Entity
Before proceeding with learning about criteria, let us define the database table and the corresponding entity class. Following is the structure of database table and sample records that will be referred throughout the examples.

id name age eid salary
1 abc 22 e001 20000
2 def 25 e002 30000
3 ghi 27 e003 40000

Entity class corresponding to the above database table is given below

import java.io.Serializable;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
 
 
@Entity
@Table(name = "employee")
public class Student implements Serializable {
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name = "id")
	private int id;
 
	@Column(name = "name")
	private String empName;
 
	@Column(name = "age")
	private int age;
 
	@Column(name="eid")
	private String employeeId;
 
	public int getId() {
		return id;
	}
 
	public void setId(int id) {
		this.id = id;
	}
 
	public String getEmpName() {
		return empName;
	}
 
	public void setEmpName(String name) {
		this.empName = name;
	}
 
	public int getAge() {
		return age;
	}
 
	public void setAge(int age) {
		this.age = age;
	}
 
        public String getEmployeeId() {
                return employeeId;
        }
        public void setEmployeeId(String eid) { 
                this.employeeId = eid; 
       }
 
}

Hibernate configuration file that we will be using is given below

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd”>

<hibernate-configuration>
   <session-factory>
      <property name=“connection.driver_class”>com.mysql.jdbc.Driver</property>
      <property name=“dialect”>org.hibernate.dialect.MySQLDialect</property>
      <property name=“hibernate.connection.url”>jdbc:mysql://localhost:3306/assessment</property>
      <property name=“connection.username”>root</property>
      <property name=“connection.password”>root</property>
      <property name=“show_sql”>true</property>
      <property name=“hbm2ddl.auto”>update</property>
   </session-factory>
</hibernate-configuration>

 

Place it inside src folder of your eclipse project.

Using Criteria api
To start using Criteria api, the first step is getting a Criteria object which belongs to org.hibernate package. This object will be used to leverage the features of Criteria classes. An org.hibernate.Criteria object is retrieved by using createCriteria method on a org.hibernate.Session object. This method takes the name of the class(or entity) on which you want the criteria methods to be applied. Following sections will clarify the various uses that a criteria object can be put to.

org.hibernate.Criteria is an interface. When its object is created, it is of type org.hibernae.internal.CriteriaImpl class.

Fetching all records
A criteria object can be used to fetch all records from a table. By all records, we mean complete rows and columns of the database table corresponding to the entity for which the criteria object is created. Example,

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
 
public class CriteriaDemo {
   public static void main(String[] args) {
	// load configuration
	Configuration configuration = new Configuration().configure();
	//add classes to be read
	configuration.addAnnotatedClass(Employee.class);
	// create session factory
	StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
			.applySettings(configuration.getProperties()).build();
	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
	// create a session
	Session session = sessionFactory.openSession();
 
	// create criteria for Employee class
	Criteria criteria = session.createCriteria(Employee.class);
	// get all employee records.
	List list = criteria.list();
	// iterate over records
	for (Employee employee : list) {
		System.out.println("Employee name: " + employee.getName() +
                        ", id: " + employee.getEmployeeId());
	}
        session.close();
	sessionFactory.close();
   }
}

First we create a session object using the method that might be already known to you and then call createCriteria method supplying it Employee class. This returns a criteria object. In order to fetch all records, list method of criteria is called which returns a java.util.List. This list contains all the records of employee table in the form of Employee objects.


When above code is executed, following query is printed at the console.

Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.age as age3_0_0_, this_.eid as eid4_0_0_ from Employee this_

The output is

Employee name: abc, id: e001
Employee name: def, id: e002
Employee name: ghi, id: e003

Ordering records
Criteria api lets you sort the fetched records on the basis of the values of a column in ascending or descending order. In other words, it lets you apply ORDER BY clause of an SQL query. This is done using criteria’s addOrder method which takes an org.hibernate.criterion.Order object. This class has asc and desc methods which allow the result set to be arranged in ascending or descending order respectively. These methods accept a String argument which is the property name on which sorting is performed. Example,

        /* Session creation code */
        // create criteria for Employee class
	Criteria criteria = session.createCriteria(Employee.class);
        // sort criteria result on id property in descending order
        criteria.addOrder(Order.desc("id"))
	// get all employee records.
	List list = criteria.list();
	// iterate over records
	for (Employee employee : list) {
		System.out.println("Employee name: " + employee.getName() +
                        ", id: " + employee.getEmployeeId());
	}

The output shows that the result set is sorted in the order of descending id values.

Employee name: ghi, id: e003
Employee name: def, id: e002
Employee name: abc, id: e001

SQL query executed by Hibernate printed at the console is given below. Notice an order by clause at the end.

Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.age as age3_0_0_, this_.eid as eid4_0_0_ from Employee this_ order by this_.id desc

Fetching single column
Above examples fetched whole records from the database table but what if you want a single or some specific columns as the result. Hibernate provides Projections and Projection classes to achieve this. Both these classes belong to org.hibernate.criterion package.
Projections class has a static method property which accepts the name of the property which should be included in the result set and returns a Projection object. This object can then be added to the criteria using its setProjection method which accepts a Projection object as argument. Example is given below. Note that list method now returns a list of String values containing names of employees and not Employee objects.

        /* Session creation code */
        // create criteria for Employee class
	Criteria criteria = session.createCriteria(Employee.class);
        // create a projection to fetch only name column
        Projection p = Projections.property("name");
        // add projection to criteria
        criteria.setProjection(p); 
	// get all employee names
	List list = criteria.list();
	// iterate over records
	for (String employeeName : list) {
		System.out.println("Employee name: " + employeeName);
	}

Output of execution of the code produces the following output

abc
def
ghi

Query printed at the console shows that only name column is fetched

Hibernate: select this_.name as y0_ from Employee this_

Fetching multiple columns
Above method only allows you to fetch a single column as the result since you can only associate only one projection to the criteria object. But that does not mean that you can not fetch more than one columns.
It is possible using a ProjectionList which again belongs to the org.hibernate.criterion package. A ProjectionList is created by calling projectionList method of Projections class.
For each property/column to be fetched a projection is created and each projection is added to the ProjectionList by calling its add method. Call add method for each property which needs to be included in the result set. Finally link this ProjectionList to the criteria object by calling its setProjection method with ProjectionList as argument.

   /* Session creation code */
 
   Criteria criteria = session.createCriteria(Employee.class);
   // create a projection list
   ProjectionList projectionList = Projections.projectionList();
   // create a projection for fetching "name" property value
   Projection nameProjection = Projections.property("name");
   // add it to list
   projectionList.add(nameProjection);
   // create a projection for fetching "employeeId" property value
   Projection ageProjection = Projections.property("employeeId");
   // add it to list
   projectionList.add(ageProjection);
   // associate projection list to criteria
   criteria.setProjection(projectionList);
   // get all employee records
   List&lt;Object[]&gt; list = criteria.list();
   // iterate over records
   for (Object[] employeeData : list) {
	System.out.println("Employee name: " + employeeData[0] +
                     ", id: " + employeeData[1]);
   }

Note that list method of criteria returns a List of Object array in this case where each item in the list is an array of columns fetched or the projections created.

Employee name: ghi, id: e003
Employee name: def, id: e002
Employee name: abc, id: e001

Fetching records based on condition
Till now we dealt with fetching all records from a table(all or selective columns) but often it is required to fetch only records which match certain condition such as fetching only those employees whose age is greater than 25, fetching student with roll number 5, fetching all movies released between years 2015-2019 etc.
In normal SQL, this can be done by applying a WHERE clause but in Hibernate, criteria api lets you achieve this too using Restrictions class from org.hibernate.criterion package. This class has static methods such as

Method Description SQL equivalent
eq Takes name of the property and a value. Those records whose property matches the given value are fetched Same as applying = operator in SQL WHERE clause
in Takes name of property and an array of values. Records whose property name has values from among array are fetched  Same as IN operator in SQL WHERE clause
between Takes name of property and two values. Records whose property value lies between the supplied values are fetched Same as BETWEEN operator in SQL WHERE clause
isNull Takes name of property. Records whose values for the supplied property are null are fetched Same as IS NULL expression in WHERE clause
isNotNull Takes name of property. Records whose values for the supplied property are non-null are fetched Same as IS NOT NULL expression in WHERE clause
ilike Takes name of the property and a value. Those records whose property contains the supplied value are fetched. Value comparison is case-insensitive Same as LIKE operator in SQL WHERE clause

The restriction is added to the criteria object using its add method. Results fetched using criteria are as per the restriction applied. Below example fetches and employee whose id is e001.

   /* Session creation code */
 
   Criteria criteria = session.createCriteria(Employee.class);
   // add condition to criteria object
   criteria.add(Restrictions.eq("employeeId", "e001"));
   // fetch employee with id "e001"
   Employee employee = (Employee)criteria.uniqueResult();
   System.out.println("Employee name: "+employee.getEmployeeName());

Note that since there will be only one result after applying the restriction, hence criteria’s uniqueResult method is used. If there are chances of multiple records, then list method should be used as before.

All methods of Restrictions class return a criterion object, which can be supplied to add method of criteria object. Also, it is possible to add multiple restrictions to a criteria object.

Query executed by Hibernate is

Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.age as age3_0_0_, this_.eid as eid4_0_0_ from Employee this_ where this_.eid=?

Note the where clause added in the query.

That’s it about criteria api in this post.

0

Mark Your Impression

Close Menu