Home arrow Java arrow Page 3 - Hibernate: Criteria Queries in Depth

Hibernate: Criteria Queries in Depth

HQL forces programmers to drop into an SQL-like syntax for certain operations. So it would seem that Hibernate developers still need to know SQL. Fortunately, Hibernate offers a set of APIs that map the SQL functionality to objects. This allows programmers to use an entirely object-oriented approach without falling back on a relational methodology. Keep reading to find out more.

Author Info:
By: A.P.Rajshekhar
Rating: 4 stars4 stars4 stars4 stars4 stars / 155
March 15, 2006
  1. · Hibernate: Criteria Queries in Depth
  2. · The Core Classes of Criteria Queries
  3. · Using Criteria Queries
  4. · A Criteria Query in the Real World

print this article

Hibernate: Criteria Queries in Depth - Using Criteria Queries
(Page 3 of 4 )

Now that the common core classes have been introduced, their usage in applications can be discussed. I already said in the last article that in SQL, DML plays  the most important role in the R(retrieve) operation of the CRUD quad. This is reflected in the core classes of Criteria API. The retrieval of data itself can be separated into four major categories:

1. Projection

2. Restriction

3. Aggregation

4. Grouping

The usage of core classes among these categories cannot be generalized. The reason for this will be evident from the details. All the examples are based on the ORDER and PRODUCTS table.

Do not confuse the term "Projection" as it is used here with the Projection class. Projection in common terms means to retrieve, and in SQL it means the "Select" clause. The "Select" clause is just a part of the services provided by the Projection class. Following is SQL query for projection of all fields of the ORDER table in SQL:


The Criteria equivalent would be:

List orders= session.createCriteria(Order.class).list();

The above statement executes the corresponding SQL statement at the database server, populates the instances of the Order ORM class, adds them to a list and returns the List object. Actually, the above statement is composed of two statements:  

Criteria criteria= session.createCriteria(Order.class)  and  

List orders=criteria.list().

The combination of such dependent statements is known as method chaining. From now on I will be using this technique extensively. The above code retrieves all the rows from the ORDER table. But what if only the data contained in one of the fields has to be retrieved, as in the following SQL query:


Here, the Projection class comes into play. The above query can be rewritten into a Criteria query as:

List products=session.createCriteria(Product.class)
     . setProjection(Projection.property(\"name\"))

It is clear from the above example that to query based on just one field, the fieldname is passed as an argument to the property() method of the Projection class. The Projection instance returned in turn becomes an argument to the setProjection() method. Similarly, to retrieve data based on two fields, ProjectionList has to be used. Hence the SQL query:


Would become

List products =session.createCriteria(Product.class).setProjection(

Now let's make the query more complex by introducing joins. What would be the equivalent of a query such as the one below:


If you think the Criteria representation of the above would be as complex, then have a look at the following:

List orders = session.createCriteria(Order.class)

It's as simple as that. The only thing to be done is to call the setFetchMode() of the Criteria class with two parameters: the name of the class with which the current class has to be joined and mode of the fetching of the data from the associated class. In the above case, the class name is actually the instance variable provided within the Order class. The mode is Join.

So retrieval is done, but there is just one problem. If the data has to be retrieved based on a condition, then what? Then Restriction has to be used.

In layman’s terms, restriction means imposing conditions. To retrieve data based on certain conditions, Restriction must be used. Here the Restriction class comes into the picture. All the conditions provided by SQL are available in Criteria. The ones most commonly used are as follows:

Restriction.between is used to apply a "between" constraint to the field.

Restriction.eq is used to apply an "equal" constraint to the field.

Restriction.ge is used to apply a "greater than or equal" constraint to the field.

 Restriction.gt is used to apply a "greater than" constraint to the field.

Restriction.idEq is used to apply an "equal" constraint to the identifier property.

Restriction.in is used to apply an "in" constraint to the field.

Restriction.isNotNull is used to apply an "is not null" constraint to the field.  

Restriction.isNull is used to apply an "is null" constraint to the field.

Restriction.ne is used to apply a "not equal" constraint to the field.     

     So a SQL such as this


      Would become   

    List orders= session.createCriteria(Order.class)

Applying the restrictions becomes easy in the case of joins as well. For example, the following query



Would become

List orders = session.createCriteria(Order.class)

Just adding the Restriction to Criteria returned by setFetchMode() does the same thing that the above given SQL does.

Through restriction conditions can be imposed on data retrieval, there are situations where the data to be retrieved has to be based on the groups of values of a column. In such conditions, Aggregation must be used. Criteria provides aggregation functionality through the Projection class itself. So to get the count of all the rows present in the ORDER table based on the ID field, the criteria query would be:

List orders = session.createCriteria(Order.class)
     .setProjection( Projections.projectionList()
     .add( Projections.count(“id”) ))

Similarly all the aggregate functions can be used as they are provided as static functions. As shown in the above example, each function takes the field name as the argument.

When the aggregation functions are used, the values may have to be grouped according to a particular field. Grouping always operates on a dataset. In Criteria Query API, grouping is provided by the Projection class. The groupProperty() method of the Projections class provides the grouping functionality. So a query like the one given below:


 Can be rewritten in Criteria query as follows:

List orders = session.createCriteria(Order.class)
     .setProjection( Projections.projectionList()
      .add( Projections.count(“id”) )
       .add( Projections.groupProperty(“id”) )

That brings us to the end of this section. In the next section I will be using the Criteria query APIs to rewrite the application written in the last part.

blog comments powered by Disqus

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials