Criteria in Hibernate
We have learned about HQL in previous articles, Now lets talk about Hibernate Criteria Query Language (HCQL) in this article.
Let us understand Hibernate Criteria Query Language (HCQL)
What is HCQL
It’s a Criteria based query language mainly used to fetch the records based on specific search criteria.
It supports complete object oriented approach for querying and retrieving the result from database based on search criteria.
HCQL can not be used to perform DDL operations like Insert,Update and Delete.
It can be used only for retrieving the records based on search conditions.
Criteria queries should be preferred when we have many optional search condtions.
org.hibernate.Criteria interface has provided several methods to add search conditions.
Most commonly used methods in Criteria are
public Criteria add(Criterion c):
This method is used to add restrictions on the search results.
public Criteria addOrder(Order o)
This method is used to define the ordering of result like ascending or descending.
public Criteria setFirstResult(int firstResult)
public Criteria setMaxResult(int totalResult)
These 2 methods are used to achieve pagination by specifying first and maximum records to be retrieved.
Example: If there are 50 records in database and if we are defining the pagination with 25 records per page
FirstResult – 1 and MaxResult – 25 and then FirstResult-26 and MaxResult -25
public List list()
This method returns the list of object on which we are searching.
public Criteria setProjection(Projection projection)
This method is used to set the projection to retrieve only specific columns in the result.
Possible restriction used in HCQL are
lt(less than)
le(less than or equal)
gt(greater than)
ge(greater than or equal)
eq(equal)
ne(not equal)
between
like
Lets consider Employee class and perform various Criteria search operations.
Step 1
Create hibernate project
Please refer Hibernate setup in eclipse article on how to do it.
Project Structure
Step 2
Update pom.xml with MYSQL and Hibernate depenedencies
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>HibernateCriteria</groupId>
- <artifactId>HibernateCriteria</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>HibernateCriteria</name>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
- <version>5.2.6.Final</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>6.0.5</version>
- </dependency>
- </dependencies>
- </project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>HibernateCriteria</groupId> <artifactId>HibernateCriteria</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>HibernateCriteria</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.6.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.5</version> </dependency> </dependencies> </project>
Step 3
Create Employee class
- package com.kb.model;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.Table;
- @Entity
- @Table(name="Employee")
- public class Employee {
- @Id
- @GeneratedValue(strategy = GenerationType.SEQUENCE)
- @Column(name = "Employee_Id")
- private int employeeId;
- @Column(name = "FirstName")
- private String firstName;
- @Column(name = "LastName")
- private String lastName;
- @Column(name = "Age")
- private int age;
- @Column(name = "Education")
- private String education;
- @Column(name = "Salary")
- private int salary;
- public int getEmployeeId() {
- return employeeId;
- }
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
- public String getFirstName() {
- return firstName;
- }
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
- public String getLastName() {
- return lastName;
- }
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getEducation() {
- return education;
- }
- public void setEducation(String education) {
- this.education = education;
- }
- public int getSalary() {
- return salary;
- }
- public void setSalary(int salary) {
- this.salary = salary;
- }
- }
package com.kb.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="Employee") public class Employee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @Column(name = "Employee_Id") private int employeeId; @Column(name = "FirstName") private String firstName; @Column(name = "LastName") private String lastName; @Column(name = "Age") private int age; @Column(name = "Education") private String education; @Column(name = "Salary") private int salary; public int getEmployeeId() { return employeeId; } public void setEmployeeId(int employeeId) { this.employeeId = employeeId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEducation() { return education; } public void setEducation(String education) { this.education = education; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } }
We have specified Primary key as employeeId and generator class as “sequence” for automatic primary key generation.
Step 4
Create hibernate.cfg.xml
- <?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>
- <!-- Database connection properties -->
- <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
- <property name="connection.username">root</property>
- <property name="connection.password">root</property>
- <!-- JDBC connection pool (using the built-in) -->
- <property name="connection.pool_size">100</property>
- <!-- SQL dialect -->
- <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
- <!-- Disable the second-level cache -->
- <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
- <!-- Echo all executed SQL to stdout -->
- <property name="show_sql">true</property>
- <!-- Format the generated Sql -->
- <property name="format_sql">true</property>
- <!-- Dont Drop and re-create the database schema on startup,Just update
- it -->
- <property name="hbm2ddl.auto">update</property>
- <mapping class="com.kb.model.Employee" />
- </session-factory>
- </hibernate-configuration>
<?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> <!-- Database connection properties --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- JDBC connection pool (using the built-in) --> <property name="connection.pool_size">100</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Format the generated Sql --> <property name="format_sql">true</property> <!-- Dont Drop and re-create the database schema on startup,Just update it --> <property name="hbm2ddl.auto">update</property> <mapping class="com.kb.model.Employee" /> </session-factory> </hibernate-configuration>
Step 5
Create Hibernate util class
- package com.kb.util;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- public class HibernateUtil {
- private static final SessionFactory sessionFactory = buildSessionFactory();
- private static SessionFactory buildSessionFactory() {
- try {
- // Create the SessionFactory from hibernate.cfg.xml
- return new Configuration().configure().buildSessionFactory();
- } catch (Throwable ex) {
- // Make sure you log the exception to track it
- System.err.println("SessionFactory creation failed." + ex);
- throw new ExceptionInInitializerError(ex);
- }
- }
- public static SessionFactory getSessionFactory() {
- return sessionFactory;
- }
- public static void shutdown() {
- // Optional but can be used to Close caches and connection pools
- getSessionFactory().close();
- }
- }
package com.kb.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception to track it System.err.println("SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { // Optional but can be used to Close caches and connection pools getSessionFactory().close(); } }
Step 6
Create PopulateData.java file to Populate Employee Table with initial data
- package com.kb.db;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.Transaction;
- import com.kb.model.Employee;
- import com.kb.util.HibernateUtil;
- public class PopulateData {
- public static void main(String[] args) {
- // Get session factory using Hibernate Util class
- SessionFactory sf = HibernateUtil.getSessionFactory();
- // Get session from Sesson factory
- Session session = sf.openSession();
- // Begin transaction
- Transaction t = session.beginTransaction();
- //Create Employee data
- Employee employee1 = new Employee();
- employee1.setFirstName("John");
- employee1.setLastName("KC");
- employee1.setAge(28);
- employee1.setEducation("PG");
- employee1.setSalary(25000);
- Employee employee2 = new Employee();
- employee2.setFirstName("Jacob");
- employee2.setLastName("JC");
- employee2.setAge(30);
- employee2.setEducation("PG");
- employee2.setSalary(30000);
- Employee employee3 = new Employee();
- employee3.setFirstName("Martin");
- employee3.setLastName("A");
- employee3.setAge(24);
- employee3.setEducation("UG");
- employee3.setSalary(20000);
- Employee employee4 = new Employee();
- employee4.setFirstName("Peter");
- employee4.setLastName("M");
- employee4.setAge(25);
- employee4.setEducation("UG");
- employee4.setSalary(22000);
- Employee employee5 = new Employee();
- employee5.setFirstName("Roshan");
- employee5.setLastName("B");
- employee5.setAge(29);
- employee5.setEducation("PG");
- employee5.setSalary(45000);
- session.save(employee1);
- session.save(employee2);
- session.save(employee3);
- session.save(employee4);
- session.save(employee5);
- // Commit the transaction and close the session
- t.commit();
- session.close();
- System.out.println("successfully persisted Employee details");
- }
- }
package com.kb.db; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import com.kb.model.Employee; import com.kb.util.HibernateUtil; public class PopulateData { public static void main(String[] args) { // Get session factory using Hibernate Util class SessionFactory sf = HibernateUtil.getSessionFactory(); // Get session from Sesson factory Session session = sf.openSession(); // Begin transaction Transaction t = session.beginTransaction(); //Create Employee data Employee employee1 = new Employee(); employee1.setFirstName("John"); employee1.setLastName("KC"); employee1.setAge(28); employee1.setEducation("PG"); employee1.setSalary(25000); Employee employee2 = new Employee(); employee2.setFirstName("Jacob"); employee2.setLastName("JC"); employee2.setAge(30); employee2.setEducation("PG"); employee2.setSalary(30000); Employee employee3 = new Employee(); employee3.setFirstName("Martin"); employee3.setLastName("A"); employee3.setAge(24); employee3.setEducation("UG"); employee3.setSalary(20000); Employee employee4 = new Employee(); employee4.setFirstName("Peter"); employee4.setLastName("M"); employee4.setAge(25); employee4.setEducation("UG"); employee4.setSalary(22000); Employee employee5 = new Employee(); employee5.setFirstName("Roshan"); employee5.setLastName("B"); employee5.setAge(29); employee5.setEducation("PG"); employee5.setSalary(45000); session.save(employee1); session.save(employee2); session.save(employee3); session.save(employee4); session.save(employee5); // Commit the transaction and close the session t.commit(); session.close(); System.out.println("successfully persisted Employee details"); } }
We are persisting 5 employee records to perform Criteria operations on it.
Step 7
Lets Create Main class to perform various HCQL Operations
- package com.kb.db;
- import java.util.List;
- import org.hibernate.Criteria;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.criterion.Criterion;
- import org.hibernate.criterion.LogicalExpression;
- import org.hibernate.criterion.Order;
- import org.hibernate.criterion.Restrictions;
- import com.kb.model.Employee;
- import com.kb.util.HibernateUtil;
- public class CriteriaExample {
- @SuppressWarnings("deprecation")
- public static void main(String[] args) {
- // Get session factory using Hibernate Util class
- SessionFactory sf = HibernateUtil.getSessionFactory();
- // Get session from Sesson factory
- Session session = sf.openSession();
- Criteria criteria = session.createCriteria(Employee.class);
- // Retrieve All the Employees using Criteria
- System.out.println("All the empoyees retrieved using Criteria");
- displayEmployeeDetails(criteria.list());
- criteria = session.createCriteria(Employee.class);
- Criterion employeeIdCriterion = Restrictions.eq("employeeId", 2);
- criteria.add(employeeIdCriterion);
- System.out.println("Employee record whose id is 2");
- displayEmployeeDetails((Employee) criteria.uniqueResult());
- criteria = session.createCriteria(Employee.class);
- Criterion greaterThanCriterion = Restrictions.gt("salary", 25000);
- criteria.add(greaterThanCriterion);
- System.out.println("All the empoyees whose salary is greater than 25000");
- displayEmployeeDetails(criteria.list());
- criteria = session.createCriteria(Employee.class);
- Criterion greaterThanOrEqualCriterion = Restrictions.ge("salary", 25000);
- criteria.add(greaterThanOrEqualCriterion);
- System.out.println("All the empoyees whose salary is greater than or equal to 25000");
- displayEmployeeDetails(criteria.list());
- criteria = session.createCriteria(Employee.class);
- Criterion lessThanCriterion = Restrictions.lt("salary", 25000);
- criteria.add(lessThanCriterion);
- System.out.println("All the empoyees whose salary is less than 25000");
- displayEmployeeDetails(criteria.list());
- criteria = session.createCriteria(Employee.class);
- Criterion lessThanOrEqualCriterion = Restrictions.le("salary", 25000);
- criteria.add(lessThanOrEqualCriterion);
- System.out.println("All the empoyees whose salary is less than or equal to 25000");
- displayEmployeeDetails(criteria.list());
- // "Like" example
- List<Employee> empList = session.createCriteria(Employee.class).add(Restrictions.like("firstName",
- "%o%")).list();
- displayEmployeeDetails(empList);
- // Pagination list example
- empList = session.createCriteria(Employee.class).addOrder(Order.desc("salary")).setFirstResult(0)
- .setMaxResults(2).list();
- displayEmployeeDetails(empList);
- // Combining multiple restrictions
- criteria = session.createCriteria(Employee.class);
- Criterion salaryGreaterThan = Restrictions.gt("salary", 25000);
- Criterion ageGreaterThanOrEqual = Restrictions.ge("age", 28);
- Criterion education = Restrictions.in("education", "PG", "Phd");
- LogicalExpression orExp = Restrictions.or(salaryGreaterThan, ageGreaterThanOrEqual);
- criteria.add(orExp);
- criteria.add(education);
- System.out.println(
- "All the empoyees whose salary is greater than 25000 or whose age is greater than
- 28 and educaton is either PG or Phd");
- displayEmployeeDetails(criteria.list());
- session.close();
- }
- private static void displayEmployeeDetails(List<Employee> employeeList) {
- for (Employee employee : employeeList) {
- displayEmployeeDetails(employee);
- }
- }
- private static void displayEmployeeDetails(Employee employee) {
- System.out.println(
- "ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
- }
- }
package com.kb.db; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.LogicalExpression; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import com.kb.model.Employee; import com.kb.util.HibernateUtil; public class CriteriaExample { @SuppressWarnings("deprecation") public static void main(String[] args) { // Get session factory using Hibernate Util class SessionFactory sf = HibernateUtil.getSessionFactory(); // Get session from Sesson factory Session session = sf.openSession(); Criteria criteria = session.createCriteria(Employee.class); // Retrieve All the Employees using Criteria System.out.println("All the empoyees retrieved using Criteria"); displayEmployeeDetails(criteria.list()); criteria = session.createCriteria(Employee.class); Criterion employeeIdCriterion = Restrictions.eq("employeeId", 2); criteria.add(employeeIdCriterion); System.out.println("Employee record whose id is 2"); displayEmployeeDetails((Employee) criteria.uniqueResult()); criteria = session.createCriteria(Employee.class); Criterion greaterThanCriterion = Restrictions.gt("salary", 25000); criteria.add(greaterThanCriterion); System.out.println("All the empoyees whose salary is greater than 25000"); displayEmployeeDetails(criteria.list()); criteria = session.createCriteria(Employee.class); Criterion greaterThanOrEqualCriterion = Restrictions.ge("salary", 25000); criteria.add(greaterThanOrEqualCriterion); System.out.println("All the empoyees whose salary is greater than or equal to 25000"); displayEmployeeDetails(criteria.list()); criteria = session.createCriteria(Employee.class); Criterion lessThanCriterion = Restrictions.lt("salary", 25000); criteria.add(lessThanCriterion); System.out.println("All the empoyees whose salary is less than 25000"); displayEmployeeDetails(criteria.list()); criteria = session.createCriteria(Employee.class); Criterion lessThanOrEqualCriterion = Restrictions.le("salary", 25000); criteria.add(lessThanOrEqualCriterion); System.out.println("All the empoyees whose salary is less than or equal to 25000"); displayEmployeeDetails(criteria.list()); // "Like" example List<Employee> empList = session.createCriteria(Employee.class).add(Restrictions.like("firstName", "%o%")).list(); displayEmployeeDetails(empList); // Pagination list example empList = session.createCriteria(Employee.class).addOrder(Order.desc("salary")).setFirstResult(0) .setMaxResults(2).list(); displayEmployeeDetails(empList); // Combining multiple restrictions criteria = session.createCriteria(Employee.class); Criterion salaryGreaterThan = Restrictions.gt("salary", 25000); Criterion ageGreaterThanOrEqual = Restrictions.ge("age", 28); Criterion education = Restrictions.in("education", "PG", "Phd"); LogicalExpression orExp = Restrictions.or(salaryGreaterThan, ageGreaterThanOrEqual); criteria.add(orExp); criteria.add(education); System.out.println( "All the empoyees whose salary is greater than 25000 or whose age is greater than 28 and educaton is either PG or Phd"); displayEmployeeDetails(criteria.list()); session.close(); } private static void displayEmployeeDetails(List<Employee> employeeList) { for (Employee employee : employeeList) { displayEmployeeDetails(employee); } } private static void displayEmployeeDetails(Employee employee) { System.out.println( "ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary()); } }
We have written many criteria on the Employee entity in the above class.
Criteria criteria = session.createCriteria(Employee.class);
This line creates the criteria object on Employee entity.
criteria.list()
This line retrieves the result from DB based on all the specified criteria.
Criterion employeeIdCriterion = Restrictions.eq("employeeId", 2);
This line creates a criterion by applying a restriction on employeeId property to fetch only the record whose employeeId is 2.
Criterion greaterThanCriterion = Restrictions.gt("salary", 25000);
This line creates a criterion by applying a restriction on salary property to fetch only those records whose salary is greater than 25000.
Criterion greaterThanOrEqualCriterion = Restrictions.ge("salary", 25000);
This line creates a criterion by applying a restriction on salary property to fetch only those records whose salary is greater than or equal to 25000.
Criterion lessThanCriterion = Restrictions.lt("salary", 25000);
This line creates a criterion by applying a restriction on salary property to fetch only those records whose salary is less than 25000.
Criterion lessThanOrEqualCriterion = Restrictions.le("salary", 25000);
This line creates a criterion by applying a restriction on salary property to fetch only those records whose salary is less than or equal to 25000.
ListempList = session.createCriteria(Employee.class).add(Restrictions.like("firstName", "%o%")).list();
This single line is performing multiple things,creating criteria and adding restriction to that whose firstName has a letter ‘o’ in it.
empList = session.createCriteria(Employee.class).addOrder(Order.desc("salary")).setFirstResult(0) .setMaxResults(2).list();
This single line is performing multiple things,creating criteria and setting starting and maximum records to achieve pagination and it is also setting the order of records to be sorted in descending order on Salary property.
- criteria = session.createCriteria(Employee.class);
- Criterion salaryGreaterThan = Restrictions.gt("salary", 25000);
- Criterion ageGreaterThanOrEqual = Restrictions.ge("age", 28);
- Criterion education = Restrictions.in("education", "PG", "Phd");
- LogicalExpression orExp = Restrictions.or(salaryGreaterThan, ageGreaterThanOrEqual);
- criteria.add(orExp);
- criteria.add(education);
criteria = session.createCriteria(Employee.class); Criterion salaryGreaterThan = Restrictions.gt("salary", 25000); Criterion ageGreaterThanOrEqual = Restrictions.ge("age", 28); Criterion education = Restrictions.in("education", "PG", "Phd"); LogicalExpression orExp = Restrictions.or(salaryGreaterThan, ageGreaterThanOrEqual); criteria.add(orExp); criteria.add(education);
In the above piece of code , we are creating multiple restrictions on different properties and then combining these restrictions in criteria to fetch the result accordingly.
First restriction is salary greater than 25000
Second restriction is age greater than 28
Third restriction is education which should be either PG or Phd.
But we have added first 2 restrictions using or Condition , so matching anyone in those 2 is also fine
Step 8
Run PopulateData.java class to create the initial data
Check the output in MYSQL DB
E:\MySql_Install\bin
Mysql –u root –p
Enter password
Use javainsimpleway;
Select * from Employee;
We can see that Emploeyee table has 5 records.
Step 9
Run the main class CriteriaExample to check the output of HCQL operations
Output