The Criteria API in Hibernate and JPA (Java Persistence API) allows developers to construct type-safe queries without relying on string-based query languages like JPQL (Java Persistence Query Language) or SQL. It provides a programmatic way to build complex queries at runtime using a fluent API and strongly-typed expressions.
When working with traditional query languages, such as JPQL or SQL, developers often need to manually construct query strings. This approach can introduce runtime errors due to incorrect syntax or typos in the query. Additionally, since the query is represented as a string, it lacks compile-time validation, which can lead to runtime exceptions if the query is malformed.
The Criteria API addresses these issues by allowing developers to build queries using a fluent and type-safe API. By using compile-time checks, the Criteria API ensures that the query is syntactically correct and avoids common typos or errors that occur when constructing the query string manually.
To get started with the Criteria API, you need to create a CriteriaBuilder
instance, which is obtained from the EntityManager
or EntityManagerFactory
. The CriteriaBuilder
provides factory methods to create various types of query components, such as CriteriaQuery
, Root
, and Predicate
.
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
Let's consider an example where we have an entity class Product
with properties such as id
, name
, and price
. We want to retrieve all products with a price greater than a certain value. Using the Criteria API, we can construct this query as follows:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root<Product> root = criteriaQuery.from(Product.class);
Predicate pricePredicate = criteriaBuilder.greaterThan(root.get("price"), 100.0);
criteriaQuery.select(root).where(pricePredicate);
List<Product> products = entityManager.createQuery(criteriaQuery).getResultList();
In the above example, we start by obtaining a CriteriaBuilder
from the EntityManager
. We then create a CriteriaQuery
instance for the Product
class. Using the from
method, we create a Root
object representing the root entity of the query.
Next, we construct a Predicate
that represents the condition for the query. In this case, we use the greaterThan
method to compare the price
attribute of the Product
with a specified value.
Finally, we select the root entity using the select
method and apply the predicate to the query using the where
method. We then execute the query using the createQuery
method of the EntityManager
and retrieve the results.
The Criteria API allows developers to compose complex queries by combining multiple expressions and predicates using logical operators such as and
, or
, and not
. It also supports joins to fetch related entities and sort the results based on specific criteria.
For example, consider a scenario where we want to retrieve all products whose price is greater than a certain value, but also filter by a specific category. We can achieve this using the Criteria API as follows:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root<Product> root = criteriaQuery.from(Product.class);
Predicate pricePredicate = criteriaBuilder.greaterThan(root.get("price"), 100.0);
Predicate categoryPredicate = criteriaBuilder.equal(root.get("category"), "Electronics");
criteriaQuery.select(root).where(criteriaBuilder.and(pricePredicate, categoryPredicate));
List<Product> products = entityManager.createQuery(criteriaQuery).getResultList();
In the above example, we create two predicates: pricePredicate
, which filters products based on price, and categoryPredicate
, which filters products based on category. We then combine these predicates using the and
method of the CriteriaBuilder
.
Using the Criteria API in Hibernate and JPA provides a powerful and type-safe way to construct queries dynamically at runtime. By leveraging the fluent API and strongly-typed expressions, developers can avoid common errors and improve the maintainability of their code. The Criteria API also enables building complex queries by composing various expressions and predicates, making it a valuable tool for querying databases in a type-safe manner.
noob to master © copyleft