Hibernate Made Easy
Simplified Data Persistence with Hibernate & JPA Annotations
Suggested Retail Price:   $54.98
Current Amazon Purchase Price:   $54.98
When you buy through us on Amazon:   $45.98
You won't find a better price!
Buy through us...Help support the site.
Most Popular Videos
'Cuz some people don't like reading...
Hibernate JPA Video CBT Tutorials Setting up the environment  Setting Up Hibernate
Hibernate and RSA IRAD Rational Software Architect Application Developer CBT Tutorial  Hibernate & Rational (IRAD)
Hibernate JPA Training  Many to Many Associations
Java Persistence With Hibernate Tutorials  Inheritance Mapping
Working with Compund Primary Keys  Compound Primary Keys
Hibernate and Eclipse Tools CBT Tutorial  Using Hibernate & Eclipse
Portlet Programming
Do you Portal? Then you need this...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

I Even Made Portlets Real Easy :)
Please Spread the Word!
Why keep HiberBook a secret???







If you found this site helpful, please tell other people about it. I'd really, really appreciate it.

SCJA Java Study Guide
Written with your success in mind...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

Get Java Certified by Sun
Is Google Clairvoyant?
Google thinks you'll like this...
What is WebSphere?
I wrote this... I know you'll love it...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

Buy it now!
Most Popular Purchases
What people are buying from us...
Popular Hibernate Purchases  Hibernate Made Easy
Popular Hibernate JPA Books  Harnessing Hibernate
The Best Spring and Hibernate Books  Java Persistence w Hibernate
Java Persistence API Books  Spring in Action
Popular Spring and JBoss Books  What is WebSphere?
Popular Spring and JBoss Books  JSR168 Portlet Programming
The SCJA Exam Questions
I wrote this, too. A Great Exam Prep...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

Get Sun Java Certified
Most Popular Tutorials
High hit reads on this site...
Hibernate and JPA Links  How Hibernate Works
Hibernate and JPA Free Tutorials  Recommended Books
Hibernate and JPA Simple Examples  Coding Advanced DAOs
Hibernate and JPA Free CBTs  Using The Criteria API
Hibernate and JPA Simple Examples  What is Hibernate?
down caret hibernate jpaAre you Harnessing It?
One of the three books you need...
Harnessing Hibernate Book by James Elliott (Author), Tim O'Brien (Author), Ryan Fowler (Author)
Read My Review
Win Yourself $100!!!
The 100% Error Free Code Challenge...

The $100 Code Challenge - No Code Errors, Guaranteed!!!
Learn How to Win a Benjamin

HardCore Hibernate
Yeah, you need this book, too...
Hibernate and JPA Simple Examples

If my book makes it Easy, this book makes Hibernate Hardcore. This is the reference standard...You need it.

Read My Review
Friendly Links
Websites we like...
Hibernate and JPA Links  JavaRanch: Big Moose Saloon
Hibernate and JPA Free Tutorials  Apache.org
Hibernate and JPA Free CBTs  Pickering is Springfield
Hibernate and JPA Simple Examples  Hibernate.org
Hibernate and JPA Simple Examples  mysql.org
Hibernate and JPA Simple Examples  Coast to Coast
Hibernate and JPA Simple Examples  What is IBM WebSphere?
Hibernate and JPA Simple Examples  Desktop Tower Defense
Is Amazon Psychic?
Amazon thinks you'll like this...

My Other Books & Stuff
Other decent books of mine :)...
Sun Certified Java Associate SCJA Study Guide  Java Associate Study Guide
SCJA Mock Exam Questions  SCJA Questions Guide
JSR-168 Portlet Development Book  JSR168 Portlet Programming
WebSphere Introduction and Support Book  What is WebSphere?
The Simpsons is based on Pickering Ontario  Pickering is Springfield
Oshawa Ontario, Discerning Bombs A book about like in Oshawa Ontario  Discerning Bombs on Oshawa
A Good Book on Hibernate and JPA the Java Persistence API  Hibernate Made Easy
From Amazon with Love
Check this stuff out...
Please Spread the Word!
Why keep HiberBook a secret???







If you found this site helpful, please tell other people about it. I'd really, really appreciate it.

More Google Stuff...
Links to entertain you...
Most Popular Purchases
What people are buying from us...
Popular Hibernate Purchases  Hibernate Made Easy
Popular Hibernate JPA Books  Harnessing Hibernate
The Best Spring and Hibernate Books  Java Persistence w Hibernate
Java Persistence API Books  Spring in Action
Popular Spring and JBoss Books  What is WebSphere?
Popular Spring and JBoss Books  JSR168 Portlet Programming
The Many Ways to Query a Database with Hibernate and JPA
How to pull JPA annotated POJOs out of the database...

Finders and Queries

One of the fine arts of enterprise programming is figuring out the best way to get all of that information that is currently in your database, out of your database, into your applications, and subsequently displayed back to the user in a manner that is both efficient and effective. Hibernate provides a variety of ways to extract information from a database, from the simple load and get methods of the Hibernate Session, to HQL, named queries, and even plain old JDBC. This chapter will explore some of the more common ways to query data from the database, including:

  • Hibernate Query Language expressions
  • Variable Injection
  • Named Queries
  • Native SQL statements

The goal of this tutorial is to demonstrate the most common mechanisms of performing database queries with Hibernate, helping you to develop a strong foundation of skills upon which you can build.

The Need for a New Query Language (HQL)

Thinking about a time a few years back, I remember when I was creating EJBs and was introduced to EJBQL, the EJB Query Language. My legacy EJBs were working just fine with the loads of SQL that was already in them, so I really didn't understand why I would want to introduce something new into the mix. Of course, looking back, my EJBs were probably a little too database driven, so perhaps it was more of my lack of good design skills that obfuscated the value of EJBQL; but I must say, I wasn't too fond of it when I first saw it.

But if you really do think about it, you will realize pretty quickly that if you're developing Java components, coding in a J2EE environment, and working with an object-oriented model, well, you should probably be thinking about your data queries in an object oriented way. And furthermore, and perhaps even more to the point, since our JPA annotated POJOs effectively abstract away the underlying database layer, the fact is, when you are designing your Java based persistence applications, you really can't be sure of what is going to be going on in the underlying database layer at deployment time or runtime.

For example, perhaps you have a JavaBean named User, and that JavaBean has a property named loginName. What is the name of the underlying field in the database? If we are writing SQL statements, the names of the database fields become very, very important, because they must exactly match the column names used in the query. This implies a knowledge of the persistence layer in the application layer, and that makes most good MVC programmers a little antsy.

However, with HQL, as with EJBQL which preceded it, you write your queries based on the properties and names of the Java objects in your domain model. That way, if the names of the underlying tables or columns ever change, your Java applications are not effected - the only thing that has to change is the mappings, or column annotations, but the actual HQL queries remain the same, insulating your Java model from possible changes at the database level. And of course, insulating the model from the persistence layer is always a penultimate goal of a good application developer. HQL makes this possible.

Hibernate Query Basics: A Review

As with any other operation in Hibernate involving a database interaction, executing a Hibernate query begins with the program gaining access to the Hibernate Session. The Hibernate Session has a createQuery method that takes any valid Hibernate Query Language String, from which a Query object can be created. A very simple HQL query that would retrieve all User objects from the underlying database would be as simple as the String "from User". So, in code, a select all Users in the database request would start off looking something like this:

Session session = HibernateUtil.beginTransaction();
Query query = session.createQuery("from User");

To actually get the results of the query, you simply ask the instance of the query object to return a java.util.List. You do this by invoking the aptly named list() method of the Query instance. The List will simply be a collection of User objects, which you can loop through at your leisure.

Session session = HibernateUtil.beginTransaction();
Query query = session.createQuery("from User");
List users = query.list();

for (int i = 0; i < users.size(); i++) {
  User user = (User) users.get(i);
  System.out.println(user.getLoginName());
}

Notice how the returned elements in the List are of type User. A quick cast allows us to pull these elements out of the List and start working with all of the yummy properties of the instance.

Selecting specific elements

Notice how the from User HQL query returned a grouping of User objects. The from User query pulls all of the fields associated with our User class out of the underlying database, and appropriately initializes the corresponding fields of the User instance. In our cheap little code, we simply printed out the user's loginName to prove that everything was working:

Session session = HibernateUtil.beginTransaction();
Query query = session.createQuery("from User");
List users = query.list();
for (int i = 0; i < users.size(); i++) {
  User user = (User) users.get(i);
  System.out.println(user.getLoginName());
}

If all we were interested in was the loginName, we could have prefaced our find User HQL query with a SELECT element, and selected only the loginName:

String hql = "SELECT loginName from User";

Note though, the result of such a query, where only one parameter is specified, is a list of elements matching the data type of the property. So, in this case, since the loginName property is defined in the User class as a String, the List returned from the query.list() method will be a collection of String objects, not a collection of Users:

Session session = HibernateUtil.beginTransaction();
String hql = "SELECT loginName from User";
Query query = session.createQuery(hql);
List names = query.list();
for (int i = 0; i < names.size(); i++) {
  String name = (String) names.get(i);
  System.out.println(name);
}

If more than one property is selected, the elements of the returned List are array elements, with the array elements matching the type and order of the elements as they appear in the select portion of the HQL statement.

The HQL where Clause & Unique Results

To narrow down the size of your queries, you'll need to use the irrepressible WHERE clause. To find a User with the loginName of mj, the corresponding HQL query would look like this:

String hql="from User where loginName = 'mj' ";

Now, assuming the loginName was a unique field in the database, and there could only be one possible row in the database where the loginName was 'mj', there's no point in returning a List via the Query object. Instead, when only one result is expected, we use the uniqueResult() method of the Query class, which returns to the calling program a simple, single, java.util.Object, which can be uneventfully cast into the appropriate object of choice.

Combining the where clause and the uniqueResult() method, our Java code would look something like this:

Session session = HibernateUtil.beginTransaction();
String hql="from User where loginName = 'mj' ";
Query query = session.createQuery(hql);
Object o  = query.uniqueResult();
User u = (User)o;
System.out.println(u.getLoginName());
System.out.println("\n\n");
HibernateUtil.commitTransaction(); 

Of course, this particular HQL query hard codes the loginName 'mj' right into the query. This doesn't really make too much sense, as you generally don't know the value you need to look up until runtime. Rather than hard coding values into an HQL query, you'll typically use variable injection instead.

JDBC and PreparedStatements: A Review

When performing a query where the criteria isn't exactly known at runtime, as in the case where we select a record based on the loginName a user provides, we need to leverage HQL's variable injection facilities. If you've ever used JDBC and worked with PreparedStatements, you'll notice a number of similarities in the philosophy of how variables are injected into HQL statements, although the syntax between HQL and JDBC statements is a little bit different.

With a JDBC PreparedStatement, a select query against the user table where the value of the loginName is not known until runtime would look something like this:

String loginName;
/*obtain the loginName from user somehow!!!*/ 
String sqlQuery = 
          "select * from user where loginName = ?";
PreparedStatement ps = con.prepareStatement(sqlQuery);
/*replace the first ? mark 
with the value held by the variable*/
ps.setString(1, loginName);
ResultSet rs = ps.executeQuery();

The idea with the above code is that the value of the user's loginName is not known until it is provided to our program, so instead of hard-coding the values into your program, you can code a normal SQL statement with a question mark, ?, in the spot where the unknown value should go. You then code some way to get this value at runtime, substitute the initialized runtime variable for the question mark in the query, and then finally, send the query to the database. That's how JDBC PreparedStatements work! As I like to say, Hibernate is very similar - but different. :)

Variable Injection with Hibernate

Hibernate uses a mechanism similar to a JDBC PreparedStatement to perform runtime variable injection into SQL statements. The Hibernate syntax is a bit different from standard JDBC code, but the idea is pretty much the same.

Rather than putting a question mark into the Hibernate Query Language String where the runtime variable needs to be inserted, as we might with JDBC, Hibernate tends to use a variable name with a colon in front of it, although using the question mark syntax is still possible. Using variable names is preferred, as you can use real names where the variables need to be inserted, rather than numbering off the question marks in a JDBC preparedStatement.

Here's how our Hibernate query string might look:

String hql = "from User where loginName = :name";

This HQL String is then passed to the createQuery method of the Hibernate Session to create a Query object:

Query query = session.createQuery(hql);

From there, a setter method on the initialized query object, which I creatively named query, is used to substitute the variable, which is defined in the HQL String as :name, with an actual value. Here, we use a value passed into the program:

query.setString("name", loginName);

Once the placeholder in the HQL query has been substituted by our intended variable, we can execute the query and obtain a unique result.

Object o = query.uniqueResult();
User user = (User)o;

Once the query is executed, we take the queryResult, which is returned as an Object, and cast it into a our User type, which can then be used in the application. It's all just that easy!

Session session = HibernateUtil.beginTransaction();
String loginName = "mj";
String hql="from User where loginName = :name";
Query query = session.createQuery(hql);
query.setString("name", loginName);
Object o = query.uniqueResult();
User user = (User)o;
System.out.println(user.getLoginName());
HibernateUtil.commitTransaction();

ORDER BY and the HQL Alias

Another helpful little token you can add to an HQL statement is the ORDER BY element. Basically, you can specify a specific property of your POJO, and tell Hibernate to sort the results of your query by that property, in either an ascending (ASC) or descending (DESC) manner.

Session session = HibernateUtil.beginTransaction();
String hql = "from User as u ORDER BY u.id ASC";
Query query = session.createQuery(hql);
List users = query.list();
for (int i = 0; i < users.size(); i++) {
  User user = (User) users.get(i);
  System.out.println("Hello World");
  System.out.println(user.getLoginName());
}
HibernateUtil.commitTransaction();

You will also notice that through a little slight of hand, I used an alias in the ORDER BY query. In any HQL query, you can use the word as to specify an alias for the class you are querying against. Here, I specified the alias u, and when the ORDER BY clause was used, I simply specified the property name using the alias, which equated to u.id.

String hql = "from User as u ORDER BY u.id ASC";

GROUP BY and HAVING

The last two elements of the SELECT query that I haven't talked about are the GROUP BY and HAVING attributes. The results of a query, or aggregate query, can be grouped together using the GROUP BY clause. Furthermore, a logical expression can be provided through the HAVING token of the HQL query as well. Our User class doesn't give us any great scenarios for using the GROUP BY and HAVING tokens, but here's a simple example that effectively demonstrates the syntax.

Session session = HibernateUtil.beginTransaction();
String hql;
hql= "from User as u GROUP BY u.id HAVING u.id > 4)";
Query query = session.createQuery(hql);
List users = query.list();
for (int i = 0; i < users.size(); i++) {
  User user = (User) users.get(i);
  System.out.println("Hello World");
  System.out.println(user.getLoginName());
}
HibernateUtil.commitTransaction();

Examples of Batch UPDATE Calls with Hibernate

For performing updates and deletes on a large number of records, Hibernate provides a fairly simple batch operation syntax. The syntax is pretty much as follows:

( UPDATE | DELETE ) FROM ? EntityName (WHERE where_conditions)

So, to change the password on all users who were lazy and silly and set their own passwords to the literal string 'password', we can issue the following HQL:

String hql="update User 
               set password = 'abc123' 
                  where password='password')";

This update will effectively change every record that has a password of 'password' to a password of 'abc123'.

One thing to note about performing a batch update or delete is the fact that we do not use the query.list() or query.uniqueResult() methods, but instead, we use the special executeUpdate() method of the Query instance. Very conveniently, this method returns a value of type int that tells us how many records were actually effected. Putting all of it together in code would look like this:

Session session = HibernateUtil.beginTransaction();
String hql = "update User 
                set password = 'abc123' 
                  where password='password')";
Query query = session.createQuery(hql);
int rowCount = query.executeUpdate();
System.out.println(rowCount + " rows were updated.");
HibernateUtil.commitTransaction();

Batch DELETE Calls with Hibernate

Batch DELETE calls with Hibernate are very similar to an update, except there's obviously no need to set any update parameters. So, to delete every user in the database with a name of 'Tim', the HQL DELETE query would look like this:

String hql = "delete User where loginName = 'Tim' ";

And again, the HQL delete query must be sent to an executeUpdate method of the Query object to both run the batch command, and subsequently return the number of rows effected. Here's how a batch delete would look in code:

Session session = HibernateUtil.beginTransaction();
String hql = "delete User where loginName = 'Tim'";
Query query = session.createQuery(hql);
int rowCount = query.executeUpdate();
System.out.println(rowCount + " rows were deleted.");
HibernateUtil.commitTransaction();  

When run, this code would delete every row in the database with the loginName of Tim. Pretty sweet, isn't it?

Examples of Hibernate Named Queries

Mingling HQL statements right there alongside your Java code is neither a manageable nor maintainable solution. Instead, it's a best practice to keep all of your HQL queries in a single, manageable location, and invoke those queries by name in your code. To facilitate this functionality, Hibernate leverages the @NamedQuery JPA annotation. To use it, you simply create a class that will contain all of your named queries, and place the @NamedQuery annotation at the top of the class.

@NamedQuery(name="user.findByLoginName",    
     query="from User where loginName = :name") 

One thing you should know about named queries is that the class that defines the @NamedQuery tag must be made part of Hibernate's AnnotationConfiguration object. Our User class is added to the AnnotationConfiguration object in our custom HibernateUtil class, so we'll add the NameQuery right before the class declaration of the User.

package com.examscam.model;
import javax.persistence.*;
import org.hibernate.Session;
import com.examscam.HibernateUtil;
@Entity
@Table(name = "user", schema = "examscam")
@NamedQuery(name="user.findByLoginName",
   query="from User where loginName = :name" )
public class User {     }

Once you have defined your @NamedQuery, and the class in which it is defined is loaded into Hibernate's AnnotationConfiguration, you can use this named query anywhere that you access the Hibernate Session.

Calling a NamedQuery in Hibernate

With the class that defines the @NamedQuery annotation made part of the Hibernate Configuration, invoking the NamedQuery is as simple as calling the Hibernate Session's getNamedQuery method, and passing along the query name. From there, you can inject any variables as needed, and then execute the query as per usual.

The following main method implements the from User where loginName = :name query in the form of a NamedQuery:

public static void main(String args[]){
  String loginName = "mj";
  Session session = HibernateUtil.beginTransaction();

    Query query =       
     session.getNamedQuery("user.findByLoginName");
query.setString("name", loginName);
  Object o = query.uniqueResult();
  User user = (User)o;
  System.out.println(user.getLoginName());
  HibernateUtil.commitTransaction();
}

Hibernate and Native SQL

And though our main focus is always Hibernate, it is worth mentioning that you can indeed issue native SQL queries through the Hibernate Session using the Session's createSQLQuery method. You simply pass in a valid SQL String, and Hibernate will return the results in a java.util.List.

Now one thing to note about native SQL queries is that what gets returned in each element of the List is simply an Object array, containing the datatype to which the queried columns map, as defined by the JPA annotations of the class. Furthermore, with a SELECT * query, we would need to know the order of the columns in the database so we can cast the incoming data properly.

The following is an example of a native SQL query that goes against a User database table with id (Integer), email, name and password fields:

public static void main(String args[]) {
  String sql = "SELECT * FROM USER";
  Session session = HibernateUtil.beginTransaction();
  SQLQuery query = session.createSQLQuery(sql);
  List users = query.list();
  for (int i = 0; i < users.size(); i++) {
    Object[] o = (Object[]) users.get(i);
    System.out.print(((Integer) o[0])); //id
    System.out.print(((String) o[1]));  //email
    System.out.print(((String) o[2]));  //name
    System.out.println(((String) o[3]));//pass
  }
}

hibernate java hibernate spring hibernate hibernate cache hibernate class hibernate collection hibernate configuration hibernate database hibernate dialect hibernate download hibernate example hibernate mapping hibernate query hibernate sql hibernate tutorial hibernate xml struts hibernate xp hibernate 3 hibernate 3.0 hibernate api hibernate caching hibernate cfg xml hibernate dao hibernate examples hibernate framework hibernate generator hibernate in action hibernate jdbc hibernate list hibernate one to one hibernate plugin hibernate properties hibernate tool hibernate tools hibernate training hibernate tutorials java persistence with hibernate jboss hibernate linux hibernate standby hibernate ubuntu hibernate xdoclet hibernate hibernate synchronizer computer hibernate disable hibernate enable hibernate hibernate 2 hibernate 3.2 hibernate annotation hibernate annotations hibernate bag hibernate batch hibernate blob hibernate button hibernate c3p0 hibernate cascade hibernate command hibernate composite id hibernate composite key hibernate config hibernate connection hibernate criteria hibernate date hibernate delete hibernate discriminator hibernate documentation hibernate ehcache hibernate entitymanager hibernate enum hibernate fetch hibernate file hibernate filter hibernate flush hibernate formula hibernate forum hibernate hbm hibernate hbm2ddl hibernate hbm2ddl auto hibernate hql hibernate id hibernate in vista hibernate inheritance hibernate insert hibernate interceptor hibernate interview questions hibernate inverse hibernate javadoc hibernate join hibernate jpa hibernate lazy hibernate lazy loading hibernate load hibernate logging hibernate many to many hibernate many to one hibernate map hibernate mapping file hibernate merge hibernate mode hibernate named query hibernate order hibernate order by hibernate org hibernate performance hibernate problems hibernate property hibernate proxy hibernate query language hibernate reference hibernate restrictions hibernate reverse engineering hibernate save hibernate saveorupdate hibernate search hibernate select hibernate sequence hibernate session hibernate sessionfactory hibernate set hibernate shortcut hibernate show_sql hibernate source hibernate sql query hibernate stored procedure hibernate template hibernate timestamp hibernate transaction hibernate type hibernate update hibernate usertype hibernate validator hibernate version how to hibernate laptop hibernate net sf hibernate netbeans hibernate org hibernate dialect org hibernate session sleep hibernate sleep vs hibernate spring and hibernate standby vs hibernate turn off hibernate vista hibernate what is hibernate windows hibernate windows xp hibernate all 150 Help java spring apache xml ajax cache cmp j2ee s truts tomcat ejb jboss jsf maven primary key ruby on rails foreign key hibernation ibatis one to one spring framework xdoclet hql hybernate jdo many to many middlegen ojb one to many

eXTReMe Tracker