Section 2

Hibernate Query Object / Hibernate Query Language

Hibernate Query Object / Hibernate Query Language is a tool that simplifies data retrieval, creation, and manipulation. Here are some important points to note about it:

  • Hibernate created a new language named Hibernate Query Language (HQL).

  • The syntax is quite similar to database SQL language.

  • The main difference is that HQL uses class name instead of table name, and property names instead of column names.

  • The Hibernate Query Object - HQL is used to retrieve data from the database.

  • Keywords, such as SELECT, FROM, and WHERE, etc. are not case-sensitive, but properties such as table and column names are case-sensitive in HQL.

  • HQL has many benefits, including that it is database independent, polymorphic queries are supported, and it is easy to learn for Java programmers.

Commonly supported clauses in HQL

  1. HQL From: HQL From is the same as a select clause in SQL.

  2. HQL JOIN: HQL supports inner JOIN, left JOIN, right JOIN, and full JOIN (e.g., select e.name, a.city from Employee e INNER JOIN e.address a).

  3. Aggregate Functions: HQL supports commonly used aggregate functions such as count(*), count(distinct x), min(), max(), avg(), and sum().

  4. Expressions: HQL supports arithmetic expressions (+, -, *, /), binary comparison operators (=, >=, <=, <>, !=), and logical operations (and, or, not), etc.

  5. HQL supports order by and group by clauses, subqueries such as SQL queries, and DDL and DML.

HQL - Interfaces

Query Interface:

  • Query is an interface that presents inside org.hibernate package.

  • A Query instance is obtained by calling Session.createQuery().

  • Query objects use SQL or Hibernate Query Language (HQL) strings to retrieve data from the database and create objects. A Query instance is used to bind query parameters, limit the number of results returned by the query, and finally, to execute the query.

  • Hibernate provides different techniques to query database, including, TypedQuery, NamedQuery and Criteria API. TypedQuery and NamedQuery are two additional Query sub-types.

Query interface should be used mainly when the query result type is unknown or when a query returns polymorphic results, and the lowest known common denominator of all the result objects is Object. When a more specific result type is expected, queries should usually use the TypedQuery interface.

Execution HQL Queries

The Query interface defines two methods for running SELECT queries:

  • Query.getSingleResult - use when exactly one result object is expected.

  • Query.getResultList - use when multiple result objects are expected.

The TypedQuery interface defines the following methods:

  • TypedQuery.getSingleResult - use when exactly one result object is expected.

  • TypedQuery.getResultList - use when multiple result objects are expected

In addition, the Query interface defines a method for running DELETE and UPDATE queries:

  • Query.executeUpdate - for running only DELETE and UPDATE queries.

HQL Methods

Here are a few important Query methods, which will be used often in Hibernate implementations:

  • getSingleResult: Execute a SELECT query that returns a single result.

  • list(): Return the query results as a list. If the query contains multiple results per row, the results are returned in an instance of Object[], but use the getResultList() method instead of list() because this is a deprecated (out of date) method.

  • getResultList(): The default implementation of the getResultList() method is in org.hibernate package. Query calls the list() method. Execute a SELECT query and return the query results as an untyped list.

Clauses in the HQL

FROM Clause:

You will use the FROM clause if you want to load a complete persistent object into memory. Following is the simple syntax of using the FROM clause:

String hql = "FROM User"; // Example of HQL to get all records of user class
TypedQuery query = session.createQuery(hql);
List<User> results = query.getResultList();
for (User u : results) {
    System.out.println("User Id: " +u.getId() + " Full name:" + u.getFullname() +" Email: " + u.getEmail() +" password" + u.getPassword());
}

WHERE Clause:

If you want to narrow the specific objects that are returned from storage, use the WHERE clause. Following is the simple syntax of using the WHERE clause:

String hql = "FROM User u WHERE u.id = 2"; // Example of HQL to get all records of user class
TypedQuery query = session.createQuery(hql);
List<User> results = query.getResultList();
for (User u : results) {
    System.out.println("User Id: " +u.getId() + " Full name:" + u.getFullname() +" Email: " + u.getEmail() +" password" + u.getPassword());
}

ORDER BY Clause:

To sort your HQL query results, you will need to use the ORDER BY clause. You can order the results by any property on the objects in the result set (ascending [ASC] or descending [DESC]). Following is the simple syntax of using ORDER BY clause:

String hql = "FROM User E WHERE E.id > 3 ORDER BY E.salary DESC"; // Example of HQL to get all records of user class
TypedQuery query = session.createQuery(hql);
List<User> results = query.getResultList();
for (User u : results) {
    System.out.println("User Id: " +u.getId() + " Full name:" + u.getFullname() +" Email: " + u.getEmail() +" password" + u.getPassword());
}

Multiple SELECT Expressions

The SELECT clause may also define composite results:

SELECT U.salary, U.fullname FROM User AS U;
TypedQuery<Object[]> queryy = session.createQuery("SELECT U.salary, U.fullname FROM User AS U", Object[].class);
List<Object[]> resultss = queryy.getResultList();
for (Object[] a : resultss) {
    System.out.println("Salary: " + a[0] + ", Full name: " + a[1]);
}

GROUP BY Clause and Aggregate function

This clause lets Hibernate pull information from the database and group it based on a value of an attribute; and typically, uses the result to include an aggregate value. Following is the simple syntax of using GROUP BY clause:

String hql = "SELECT SUM(U.salary), U.city FROM User U GROUP BY U.city"; //The query returns Object[] arrays of length 2
TypedQuery query = session.createQuery(hql);
List<Object[]> result =query.getResultList();
for (Object[] o : result) {
    System.out.println("Total salary "+o[0] +" | city: "+ o[1] );
}

Hibernate Parameterized Query

Using Named Parameters:

Hibernate supports named parameters in its HQL queries. Following is the simple syntax of using named parameters:

String hql = "FROM User u WHERE u.id = :id";
TypedQuery query = session.createQuery(hql);
query.setParameter("id", 4);
List<User> result = query.getResultList();
for (User u : result) {
    System.out.println("User Id: " + u.getId() + " Full name:" + u.getFullname() +" Email: " + u.getEmail() +" password" + u.getPassword());
}

Overview of Hibernate Named Query

Hibernate provides “NamedQuery” that can be defined at a central location and can be used anywhere in the code. Here are some important points to note about it:

  • Hibernate named query is a way to use any query by some meaningful name.

  • We can create a NamedQuery for both HQL and Native SQL.

  • A named query is a statically defined query with a predefined, unchangeable query string.

  • Named queries are compiled when SessionFactory is instantiated.

  • They are validated when the session factory is created.

Example - Hibernate Named Query

NamedQuery can be defined in Hibernate mapping files or by using Hibernate annotations. Named query definition has two important attributes:

  • name: The name attribute of a named query by which it will be located using hibernate session.

  • query: Here you will give the HQL statement to get executed in the database.

@NamedQueries({
    @NamedQuery(name="updateEmpById", query = "update Employee set Name = :name where id = :id"),
})

Advantages of Named Queries

  1. Fail fast: Their syntax is checked when the session factory is created, making the application fail fast in case of an error.

  2. Reusable: They can be accessed and used from several places, which increases reusability.

JDBC vs. Java Hibernate

  • Hibernate performs an Object-Relational Mapping (ORM) framework, while JDBC is simply a database connectivity API.

  • JDBC is database dependent (i.e., one needs to write different codes for different databases). Hibernate is database-independent and the same code can work for many databases with minor changes.

  • The benefits of using Hibernate over JDBC include: reduced boilerplate code, automatic Object Mapping, and easy migration to a new database.

Summary

Hibernate ORM stands for Object Relational Mapping. Hibernate Query Language (HQL) is used as an extension of SQL and is very simple, efficient, and flexible for performing complex operations on relational databases without writing complicated queries. Hibernate provides “NamedQuery” that can be defined at a central location and can be used anywhere in the code.

References

Last updated