The Criteria API in Hibernate provides a programmatic way to construct queries for retrieving entities from the database. Instead of writing HQL or SQL queries as strings, you can use a fluent API to build queries using Java method calls.
Here are some of the benefits of using the Criteria API:
- Type safety: You can build queries using Java method calls, which are checked at compile time for correctness, rather than constructing HQL or SQL queries as strings, which can be prone to syntax errors.
- Dynamic queries: You can construct queries dynamically based on runtime conditions, using conditional expressions and logical operators.
- Composition: You can reuse and compose Criteria objects to build more complex queries.
- Automatic association fetching: You can specify which associations to fetch eagerly or lazily, and the Criteria API will generate the appropriate SQL joins.
- Pagination: You can specify how many results to retrieve at a time, and use the built-in methods to iterate over the results.
Here are some code examples that demonstrate some of the key features of the Criteria API:
1- Associations:
2- Restrictions:
3- Ordering:
4- Projections:
5- Aggregation:
First, we will configure everything which will be needed-
1- Classes
2- Hibernate Configuration file
3- Hibernate Mapping File
4- Create the Hibernate SessionFactory object
5- Open a Hibernate session
1- Class (Person),
import java.util.Date;
public class Person {
private long id;
private String name;
private Date dob;
private Address address;
//getters and setters
}
1.l – Class(Address)-
public class Address {
private long id;
private String street;
private String city;
private String state;
private String zip;
private Person person;
// getters and setters
}
2- Hibernate configuration file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="Person.hbm.xml"/>
<mapping resource="Address.hbm.xml"/>
</session-factory>
</hibernate-configuration>
3- Hibernate Mapping File
A- Person class-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Person" table="person">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<property name="dob" column="dob"/>
<many-to-one name="address" class="Address" fetch="join">
<column name="address_id" not-null="true" />
</class>
</hibernate-mapping>
B- Address class-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Address" table="addresses">
<id name="id" type="long">
<column name="address_id" />
<generator class="native" />
</id>
<property name="street" column="street" />
<property name="city" column="city" />
<property name="state" column="state" />
<property name="zipCode" column="zip_code" />
<set name="persons" inverse="true" cascade="all">
<key column="address_id" />
<one-to-many class="Person" />
</set>
</class>
</hibernate-mapping>
4- Create the Hibernate SessionFactory object
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = cfg.buildSessionFactory();
5- Open a Hibernate session
Session session = sessionFactory.openSession();
-Now we will save some data and then use criteria features-
import java.util.Date;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
public class Main {
public static void main(String[] args) {
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
// Person.hbm.xml is already defined
SessionFactory sessionFactory = cfg.buildSessionFactory();
// open a session
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// create some Address objects
Address address1 = new Address("123 delhi St", "Delhi", "DLI", "10001");
Address address2 = new Address("456 noida St", "Noida", "No", "02115");
Address address3 = new Address("789 lucknow St", "Uttar pradesh", "UP", "94110");
// create some Person objects
Person person1 = new Person("Kuldeep kaushik", new Date(80, 3, 15));
person1.setAddress(address1);
Person person2 = new Person("Deep sharma", new Date(85, 8, 25));
person2.setAddress(address2);
Person person3 = new Person("Bishal Jankar", new Date(90, 5, 10));
person3.setAddress(address3);
Person person4 = new Person("somi sharma", new Date(75, 1, 1));
person4.setAddress(address1);
// save the objects to the database
session.save(address1);
session.save(address2);
session.save(address3);
session.save(person1);
session.save(person2);
session.save(person3);
session.save(person4);
// commit the transaction
tx.commit();
//----Now we can use criteria features-----
// create a Criteria object
Criteria criteria = session.createCriteria(Person.class);
// 1. Associations
// join with the Address entity
criteria.createAlias("address", "a")
.add(Restrictions.eq("a.city", "Delhi"));
// 2. Restrictions
// add a restriction on the date of birth
Date startDate = new Date(80, 0, 1);
Date endDate = new Date(90, 0, 1);
criteria.add(Restrictions.between("dob", startDate, endDate));
// 3. Ordering
// order the results by name in descending order
criteria.addOrder(Order.desc("name"));
// 4. Projections
// select the name and date of birth properties and return a list of custom objects
criteria.setProjection(Projections.projectionList()
.add(Projections.property("name"), "name")
.add(Projections.property("dob"), "dob"))
.setResultTransformer(Transformers.aliasToBean(PersonSummary.class));
// 5. Aggregation
// count the number of persons in the result set
criteria.setProjection(Projections.rowCount());
// execute the query and retrieve the results
List<PersonSummary> results = criteria.list();
// close the session
session.close();
}
}