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
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
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
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?
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
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
Is Amazon Psychic?
Amazon thinks you'll like this...

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
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
Is Amazon Psychic?
Amazon 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!
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
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
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 :)
Is Google Clairvoyant?
Google thinks you'll like this...
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.

Doing CRUD Operations with Hibernate and JPA
How to create, retrieve, update and delete with Hibernate...

Okay, assuming you're following allong in these tutorials, I'm just over the moon that we've got a basic Hibernate environment configured, we've got some code compiled, and we're successfully saving data to our database. Plus, we've effectively used a few JPA annotations in our code as well. All in all, were making good progress, but there's still a long way to go before we can say that we've mastered Hibernate.

This tutorial will go beyond the basic save functionality we saw in the previous tutorial,, and take a look at all four of the basic CRUD operations, namely:

  • Create Operations (a quick review of the previous tutorial)
  • Retrieve Operations
  • Updating Functionality
  • Delete and Destroy Functionality

Interestingly enough, on the topic of data retrieval, there are actually a few different ways that entities can be brought into your application given a unique primary key. This chapter will finish off by discussing these entity acquisition options, as we try and shed some light on their differences and benefits.

Create (We've Seen This Before)

All database driven applications revolve around the four basic CRUD operations: Create, Read (retrieve?), Update and Delete (destroy?). In previous chapters, we examined the code that was required to get the Hibernate framework to create a new database record based on an instance of the User class. We're going to start off this chapter by leveraging that knowledge of Hibernate as we create a new class called CrudRunner.

Take a look at the starter code for the CrudRunner below. As you can see, the CrudRunner is a simple Java class with a static create method and a runnable main method, that for now, simply calls the create method. As far as the create method goes, there's nothing new in there. It's the same Hibernate code we saw in the previous tutorial when we learned how to save the state of a User instance to the database.

All That Plumbing Code

All of the plumbing code that has to do with creating a Hibernate AnnotationConfiguration object, which is needed to create a SessionFactory, which is eventually used to generate a Hibernate Session, is very verbosely coded in the CrudRunner class. We're going to repeat that stuff ad nauseum in this chapter. Of course, we could always factor it out into a single, reusable method, but we'll save that for another time and place. For now, it's probably a good learning strategy to be further exposed to the fundamental code that's required to get Hibernate to work.

The CrudRunner Class: First Iteration

package com.examscam;
/* Notice the com.examscam package!!! */
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.examscam.model.User;
import java.util.*;
public class CrudRunner {
  public static void main(String[] args) {
/* Run all the static methods (currently only 1) */
    CrudRunner.create(); 
  }




  public static void create (){
/* Create the config object, reading from the
hibernate.cfg.xml file. */
    AnnotationConfiguration config =  
                    new AnnotationConfiguration();
/* Make sure all annotated classes 
are added to the configuration */
    config.addAnnotatedClass(User.class);
    SessionFactory factory;
/* Obtain the SessionFactory after calling 
the config() method of the A
nnotationConfiguration instance. */
    factory = 
         config.configure().buildSessionFactory();
/* Get a Hibernate Session */
    Session session = factory.getCurrentSession();
    session.beginTransaction();
/* Create and initialize an instance 
of a JPA annotated class */
    User user = new User();
    user.setPassword("abc123");
/* Have the instance touch the session and then 
commit the transaction */
    
session.save(user);
    session.getTransaction().commit();  }
}

Retrieving and Querying Data with Hibernate

So, we should be pretty solid on creating a new record in the database using Hibernate, seeing that we've done it a few times. The next question is: how do we query and see all of that fabulous information that we have previously stuffed inside of our database?

Well, querying a database with Hibernate is a little bit more of an involved process than simply creating a new record. I mean, you have to create a special query object, you have to pass some special Hibernate 'SQL' to the createQuery method of the Hibernate session, you have to throw the results of your query into a java.util.List object, and then, after sprinkling in a little Haitian Voodoo, you do a few casts and subsequently inspect the data that Hibernate throws back at you. As I said, querying the database is a slightly more involved process than simply saving the state of a JPA annotated POJO, but don't be intimidated. In the grand scheme of things, pulling information out of a database using Hibernate really isn't all that difficult.

I'm going to add a new static method to my CrudRunner class called retrieve that has all the code in it that's needed to pull all of the records out of the user database table. Take a look at it; we'll debrief it in a moment.

public static void retrieve() {
  AnnotationConfiguration config = 
                     new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory;
  factory = config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  java.util.List allUsers;
  Query queryResult=session.createQuery("from User");
  allUsers = queryResult.list();
  for (int i = 0; i < allUsers.size(); i++) {
    User user = (User) allUsers.get(i);
    System.out.println(user.getPassword());
  }
  session.getTransaction().commit();
}
 

Debriefing the retrieve() Method

The retrieve method starts off with some redundant and repetitive Hibernate plumbing code that basically initializes the Hibernate infrastructure classes and gets our Java program ready to interact with the database. Again, you will notice that a Hibernate Session is obtained from the SessionFactory, which itself is built from Hibernate's AnnotationConfiguration object. This Hibernate Session then begins a transaction, which is something we should do every time we interact with our persistence store. Of course, we've seen all of this plumbing code umpteen times before. Don't worry, we'll eventually look at factoring this repetitive code out into a helper method or HibernateUtil class or something, but for now, we'll leave it in, just for the sake of simplicity.

 
  /* your standard Hibernate connection code */
  AnnotationConfiguration config = 
                      new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory;
  factory = config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();

Querying the Database

After the Hibernate session is obtained, we declare an object of type java.util.List, to which we assign the variable name allUsers. Basically, when we do a standard, non-unique query of the database, we can expect a result to be returned to us in the form of a java.util.List. The allUsers list will hold the results of our from User query.

java.util.List allUsers;

Say Hello to HQL

Once we have our List for holding the query results, and this is a pretty important point, the createQuery method is invoked on the Hibernate session, with the String "from User" being passed in as the argument.

 
  /* specifically the org.hibernate.Query */
  Query queryResult = session.createQuery("from User");   
  allUsers = queryResult.list();

As you have probably guessed, the literal String "from User", which is passed into the Hibernate Session's createQuery method, is a special type of query statement that is derived from a Hibernate specific query language, HQL. For now, the "from User" String can be thought of as the object oriented equivalent of SELECT * FROM USER.

  Query queryResult=session.createQuery("from User");   
  allUsers = queryResult.list();

However, don't be fooled by what may appear on the surface to be a great similarity between standard SQL and the query language used by Hibernate. The Hibernate Query Language, HQL, is actually an object-oriented data query language, meaning that HQL understands object oriented concepts such as association, inheritance, aggregation and polymorphism. HQL is pretty awesome once you get into it, but it is definitely different from SQL.

Execution of the createQuery("from User") method call returns a Hibernate object called a Query. Calling the list() or iterate() method of the Hibernate Query object will trigger a database call that will execute the given query, and return a collection of JavaBeans that match the type and criteria of the HQL statement. As you could imagine, the list() method of the Query object returns a java.util.List of JavaBeans, whereas the iterate() method returns an object the implements the java.util.Iterator interface.

allUsers = queryResult.list();

Looping through the List

So, when we invoke the list() method on the Query instance, we get a java.util.List in return. I guess the big question is then: what exactly does this java.util.List contain?

Well, it contains instances of the User class, representing the data in the underlying user table of the database.

A Subtle Distinction

Now, since the POJO and the database table are both named User, an important little subtlety may have been missed. When the HQL statement references the User, it is actually referencing the Java class named User, not the database table named user. This is a subtle but extremely important distinction. You see, we could change the name and location of the underlying database table and infrastructure, but so long as our User class is mapped accurately to the underlying datastore, the HQL query doesn't have to change. You see, our HQL queries are based on our Java classes, and Hibernate translates those HQL queries into the appropriate SQL needed to manipulate the underlying database. Of course, Hibernate does all of those translations behind the scenes, effectively insulating Java developers from any changes that might happen to the underlying database. Awesome, eh?

Looping through the Query Results

Looping through the list, and extracting a User instance out of the List, with a combination of the List's get(int) method and a handy cast, gives us access to all of the User instances returned by the query.

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

The CrudRunner's retrieve() Method

Once you have a User instance both extracted from the List and cast into the appropriate type, it is completely up to the you with regards to what you want to do with it. In this example, we simply print out the password of the user instance to the console, which, given the fact that I'm looping through every instance in the List, will provide me the passwords of all of the entities in the user table of the database.

And that's pretty much it! To retrieve data from the database, you simply leverage the Hibernate Session's createQuery method, pass in some HQL, convert the guts of the returned Query object into an easy to use List, and then loop through the collection of POJOs contained in the List. It's just that easy!

public static void retrieve() {
  /* your standard Hibernate connection code */
  AnnotationConfiguration config = 
                             new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory;
  factory = config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  System.out.println("Querying the whole database...");
  java.util.List allUsers;
  Query queryResult=session.createQuery("from User");
  allUsers = queryResult.list();
  
  System.out.println("Number of rows: " + allUsers.size());
  
  for (int i = 0; i < allUsers.size(); i++) {
    User user = (User) allUsers.get(i);
    System.out.println(user.getPassword());
  }
  System.out.println("Database contents delivered...");
  session.getTransaction().commit();
}
 

Retrieving a Unique Entity with Hibernate

The retrieve method we just coded dropped a pretty heavy hammer on our database, returning all of the entities in the underlying system via the from User HQL query. However, not all queries are interested in obtaining a massive resultset from the database. Quite often, database queries should return either zero or one unique result from the database. Let's explore how we can handle the scenario where a query should, at most, return one, single, unique result from the database.

The primary key of the User, named id, is a unique value that can't be duplicated in the user table. If we were to query the user table on the id alone, we should never receive more than one record in return. So, let's do an HQL query that looks for a User, based on a primary key of a User already added to your database. I'm going to use the id of 1.

A Note About Primary Keys

The retrieveFromId method we are about to create will use HQL and something called variable injection to retrieve a unique entity from the database. The real objective of this method is to explore HQL a little bit deeper, and demonstrate how to handle queries that will only return one or zero results.

However, it should be noted that the Hibernate Session provides two very helpful methods for retrieving a single entity from a database if you know the primary key for the record, with those methods being load() and get(). We'll track those methods down at the end of this tutorial. I just wanted to mention that, if you do have a primary key for an entity, there are other, potentially easier ways to retrieve the associated instance with Hibernate.

Variable Injection Queries: Hibernate vs. SQL

When performing a query where the criteria isn't exactly known until runtime, we need to take advantage of 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 may be a tiny bit different.

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

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

Notice the SQL code of select * from user where id = ?, with an emphasis on the question mark. When this code is run, the value of the id is not known until runtime, so it must be garnered through the user, or perhaps, from some other part of the program. So, instead of hard coding in a value for the id, you just code the 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, substituting the initialized runtime variable for the question mark in the query using one of the methods of the JDBC PreparedStatement object. Once the ? is initialized with a real value, you send the query to the database. That's how JDBC PreparedStatements work. Hibernate is similar, but different. Let's take a look at how Hibernate would achieve the same result.

Variable Injection with Hibernate

Hibernate uses a syntax that is very similar to that of a JDBC PreparedStatement to perform runtime variable injection with an HQL statement. But while the syntax may be a bit different, 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, HQL statements typically use a variable name with a preceding colon. This is actually a bit of an improvement over using the old question mark, because you can use real names for where the variables need to be inserted, rather than rhyming off the question marks as you typically do with JDBC PreparedStatements. Here's how our Hibernate query String might look when leveraging the facilities of variable injection:

String queryString = "from User where id = :id";

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

Query query = session.createQuery(queryString);

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

query.setInteger("id", idVariable);

Once the placeholder in the HQL query has been substituted by our intended variable, we can execute the query:

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

Once the query is executed, we take the queryResult, which is returned as an Object, and cast it into a User. Once the cast is completed, it's totally up to you what to do with the instance. It's all just that easy!

Returning a Unique Result

A notable difference between the Hibernate code used to obtain a unique result, as opposed to a query that returns multiple rows, is the name of the method invoked on the Hibernate Query object. When you expect a single row to be returned from the database, you invoke the query object's uniqueResult() method. When you expect multiple rows to be returned, you use the Query's list() method.

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

Let's add a static retieveFromId method to the CrudRunner class that leverages all of our newfound knowledge on the topic of variable injection. The full method that returns a single User instance, given a primary key provided by the calling program, is as follows (note that a primary key of 1 is hard coded into the main method.):

public static User retrieveFromId(int idValue) {
  AnnotationConfiguration config =  new   AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory;
  factory = config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  String queryString = "from User where id = :id";
  Query query = session.createQuery(queryString);
  query.setInteger("id", idValue);
  Object queryResult = query.uniqueResult();
  User user = (User)queryResult;
  session.getTransaction().commit();
  System.out.print(user.getPassword());
  return user;
}
public static void main(String[] args) {
  CrudRunner.create();
  CrudRunner.retrieve();
  CrudRunner.retrieveFromId(1);   /* id of 1 */
}
 

Updating Database Records with Hibernate

So far, we've mastered the 'C' and 'R' of the CRUD acronym. Okay, maybe saying that we've mastered them is going a bit far, but we've been exposed to them, and we're getting a good idea of how they work. The next letter we have to tackle is the 'U,' or the update operation.

The process of updating a record is fairly simple. All you have to do is get a User object, update some of its information, and then pass that updated User POJO to the Hibernate Session.

For my little example, I'm going to update all of the passwords in the User table, changing all existing passwords to the word 'password.' So, to do that, I'll first retrieve all of the records from the database in the form of a java.util.List, using the techniques that were mastered when dealing with the retrieve operation. I will then pull the User objects out of the java.util.List, one at a time, and call the setter on the User POJO, updating the password of the User instance to the word 'password.'

/* update an instance of the User class */
user.setPassword("password");

After updating the User instance, I'll then pass the updated instance to the update method of the Hibernate Session.

/* pass the updated user to the 
session's update method*/
session.update(user);

Of course, nothing is guaranteed to be updated until the transaction is committed, so, once all of the User objects in the java.util.List are updated, the getTransaction().commit() method is invoked on the Hibernate Session.

session.getTransaction().commit();

The Updated CrudRunner

Here's the CrudRunner class with the updateAll method contained within. The meat of the create and retrieve methods have been scratched out for the sake of brevity.

public class CrudRunner {
  public static void main(String[] args) {
    CrudRunner.create();
    CrudRunner.retrieve();
    CrudRunner.retrieveFromId(1);
   CrudRunner.updateAll();
  }
  public static void create(){  }
  public static void retrieve(){  }
  public static User retrieveFromId(int idValue) {  }
  public static void updateAll() {
    AnnotationConfiguration config = 
                             new AnnotationConfiguration();
    config.addAnnotatedClass(User.class);
    SessionFactory factory;
    factory = config.configure().buildSessionFactory();
    Session session = factory.getCurrentSession();
    session.beginTransaction();

    java.util.List allUsers;
    System.out.println("Updating all records...");
    Query queryResult = session.createQuery("from User");
    allUsers = queryResult.list(); 
    System.out.println("# of rows:"+allUsers.size());

    for (int i = 0; i < allUsers.size(); i++) {
      User user = (User) allUsers.get(i);
      System.out.println(user);
      user.setPassword("password");
      session.update(user);
    }

    System.out.println("Database table updated...");
    session.getTransaction().commit();
  }
}

save, update & saveOrUpdate

In an earlier tutorial, when we saved a User instance to the database, we used the saveOrUpdate method. When we tackled the create method of the CrudRunner, we used save. Now that we are updating instances, we are using the update method. It's all kinda confusing, and people often wonder which one of the three methods they should use. Basically, when you have an entity that does not have a primary key, and you know that it needs to be saved as a new record to the database, you can use the save() method. A nice thing about the save method is that it returns the primary key generated as the new instance is saved.

public Serializable save(Object object)  
 throws HibernateException

Persist the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.) -Hibernate API JavaDoc

On the other hand, the update() method will do just that, update the database record that is associated with the entity being passed to the method. The method returns void, throws the HibernateException, and expects the entity passed in to have a primary key associated with it.

public void update(Object object)  
   throws HibernateException

Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. -Hibernate API JavaDoc

Finally, the saveOrUpdate() method intelligently combines the save and update functionality, knowing to create a new record for an instance passed in that does not have a primary key, and updating the associated record if the instance passed in does have a primary key associated with it.

public void saveOrUpdate(Object object) 
   throws HibernateException

Either save(Object) or update(Object) the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking). -Hibernate API JavaDoc

How to Delete A Record with Hibernate

The final function associated with the acronym CRUD is delete, or destroy; whichever term you prefer. Deleting a record using the Hibernate framework is, in many respects, remarkably similar to the coding of an update, with the exception of the fact that the word update gets transposed with the word delete.

Once we obtain the Hibernate Session, all we need to do to delete a record is pass an object of the appropriate type to the Session's delete method. Of course, for this example, the appropriate type is an instance of the User class. The only really important piece of information the User instance needs to contain is the primary key of the record to be deleted. Once a valid User instance, with an appropriate primary key, is passed to the Hibernate Session's delete method, and a transaction commit is issued, the corresponding record is deleted from the database.

Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
User user = new User();
user.setId(2); /*won't work if setId 
                 is a private method*/
session.delete(user);
session.getTransaction().commit();

Looking at the code above, a delete method that hard codes an id into an instance of a User (which actually shouldn't be possible, because the setId(int) method of the User class should be private) isn't a good idea. Actually, arbitrarily picking a primary key out of thin air is a very, very bad idea. But, if a user record with a primary key of 2 does in fact exist within the database, then after the session.getTransaction().commit() method is invoked, the corresponding record in the database would be deleted.

Again, persistent objects should initially be pulled from the database when you want to delete them, as opposed to just arbitrarily picking a primary key out of thin air. A better example might be the following deleteAll method, which looks up all the entities in the user table, and then quite destructively, one at a time, deletes every record in the database. A violent method for sure, but extreme violence is justifiable if it helps us learn.

Deleting Every Database Record with Hibernate

Our CrudRunner has an updateAll method, so why not add a deleteAll method as well? The syntax of the deleteAll method is very similar to that of the updateAll, with the exception of the fact that we call the delete method on the Hibernate session, as opposed to the update method.

public static void deleteAll() {
  AnnotationConfiguration config = 
                             new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory;
  factory = config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  java.util.List allUsers;
  System.out.println("Deleting all records...");
  Query queryResult = session.createQuery("from User");
  allUsers = queryResult.list(); 

  for (int i = 0; i < allUsers.size(); i++) {
    User user = (User) allUsers.get(i);
    System.out.println(user);
    session.delete(user);
  }
  System.out.println("Database contents deleted...");
  session.getTransaction().commit();
}

Again, this method is very similar to the updateAll() method, where we use the Hibernate Session, the createQuery method, and some HQL in the form of the select String "from User". Once the List of query results are returned to us, we hold the results in a java.util.List, and then loop through the List, one entity at a time, extracting our User POJOs out of the list, and issuing a session.delete(user); invocation. Finally, when the looping is complete, the session.getTransaction().commit() method is issued, and our User database table is empty, because we have deleted everything in it. It's just that easy.

The Fabulous, Full, CrudRunner Class:

package com.examscam;
import java.util.List; import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.Query;import org.hibernate.Session;
import org.hibernate.SessionFactory; import com.examscam.model.*;
public class CrudRunner {
 public static void main(String[] args) {
  CrudRunner.create();CrudRunner.retrieve();CrudRunner.deleteAll();
  CrudRunner.retrieveFromId(1);CrudRunner.updateAll();
 }
 public static void create() {
  AnnotationConfiguration config = new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory= config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  User user = new User();user.setPassword("abc123");
  session.save(user);
  session.getTransaction().commit();
 }

 public static void retrieve() {
  AnnotationConfiguration config = new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory= config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  Query queryResult = session.createQuery("from User");
  java.util.List allUsers;
  allUsers = queryResult.list();
  for (int i = 0; i < allUsers.size(); i++) {
   User user = (User) allUsers.get(i);
  }
  session.getTransaction().commit();
}
 public static User retrieveFromId(int idValue) {
  AnnotationConfiguration config = new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory= config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();/*lets hope an id of 1 exists!*/
  String queryString = "from User where id = :id";
  Query query = session.createQuery(queryString);
  query.setInteger("id", idValue);
  Object queryResult = query.uniqueResult();
  User user = (User)queryResult;session.getTransaction().commit();
  return user;
 }
 
 public static void updateAll() {
  AnnotationConfiguration config = 
                           new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory= 
                  config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  List allUsers;
  System.out.println("Updating all records...");
  Query queryResult = session.createQuery("from User");
  allUsers = queryResult.list(); 
  System.out.println("# of rows: "+ allUsers.size());
  for (int i = 0; i < allUsers.size(); i++) {
   User user = (User) allUsers.get(i);
   System.out.println(user);
   user.setPassword("password");
   session.update(user);
  }
  System.out.println("Database contents updated...");
  session.getTransaction().commit();
 }
 
 public static void deleteAll() {
  AnnotationConfiguration config =  new AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory=config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  List allUsers;
  session.beginTransaction();
  Query queryResult = session.createQuery("from User");
  allUsers = queryResult.list(); 
  for (int i = 0; i < allUsers.size(); i++) {
   User user = (User) allUsers.get(i);
   System.out.println(user);
   session.delete(user);
  }
  session.getTransaction().commit();
 }
}

Loading Entities with Hibernate

Now, earlier in this tutorial, we looked at the hypothetical example where you had the primary key of an entity, and wanted to query the database and have Hibernate return the unique User instance associated with that primary key. The Haitian Voodoo required to perform that retrieval task looked something like this:

public static User retrieveFromId(int idValue) {
  AnnotationConfiguration config =  
                       new   AnnotationConfiguration();
  config.addAnnotatedClass(User.class);
  SessionFactory factory;
  factory = config.configure().buildSessionFactory();
  Session session = factory.getCurrentSession();
  session.beginTransaction();
  String queryString = "from User where id = :id";
  Query query = session.createQuery(queryString);
  query.setInteger("id", idValue);
  Object queryResult = query.uniqueResult();
  User user = (User)queryResult;
  session.getTransaction().commit();
  System.out.print(user.getPassword());
  return user;
}

Taking a primary key, and using it to demonstrate variable injection and the retrieval of a unique entity was very androgologically sound, but the fact of the matter is, if you actually have the primary key of an entity, there is a much easier, or should I say "a couple of much easier ways" to retrieve the corresponding entity from the database. We'll demonstrate those ways by coding a few methods into a new class called the LoadRunner.

The LoadRunner Class

The LoadRunner class is going to have a runnable main method, and two static methods, named callGet and callLoad, which will be used to demonstrate the two different ways you can get at an entity given its associated primary key. For now, I've coded in all the redundant code we need to have each method connect to the database, create a session, and start a transaction. I know that all of this Hibernate plumbing code is getting repetitive; we'll factor it out into a HibernateUtil class soon enough.

package com.examscam;
import org.hibernate.*; 
import com.examscam.model.User;
import org.hibernate.cfg.AnnotationConfiguration;
public class LoadRunner {
  public static void callLoad(){
   AnnotationConfiguration config
                    = new AnnotationConfiguration();
   config.addAnnotatedClass(User.class);
   SessionFactory factory=
             config.configure().buildSessionFactory();
   Session session = factory.getCurrentSession();
   session.beginTransaction();
/***** load code will go here *****/
   session.getTransaction().commit();
  }
  public static void callGet() {
   AnnotationConfiguration config
                    = new AnnotationConfiguration();
   config.addAnnotatedClass(User.class);
   SessionFactory factory=
             config.configure().buildSessionFactory();
   Session session = factory.getCurrentSession();
   session.beginTransaction();
/***** get code will go here *****/
   session.getTransaction().commit();
  }
  public static void main(String[] args) {
    LoadRunner.callLoad();
    LoadRunner.callGet();
  }
}

The callGet Method

Within the session.beginTransaction() and the session.getTransaction().commit methods, we want to use the Hibernate Session to take a given primary key, and provide our program with the entity associated with that primary key in the database. It's all a pretty simple process. To get an entity from the underlying persistence store, all you have to do is call the Hibernate Session's get method, and provide two arguments: the Java class associated with the entity that your are retrieving, which in this case would be the User.class, and the actual primary key associated with the record. I know that I have a user in the database with a primary key of 1, so the number one will be used to test my methods.

Here's all the code you need to resurrect a User instance from the database using the Hibernate Session's load method:

session.beginTransaction();
User user = (User)session.get(User.class, new Long(1));
System.out.println(user.getPassword());
session.getTransaction().commit();

And that's about it! You simply call the load method of the Hibernate Session, provide the class type and the primary key as parameters, and then cast the object that is returned from Hibernate back into the appropriate Java type. From there, you can do just about anything with your JavaBean that you want. In this case, I simply print out the password of the User instance. It's all just so easy.

Now, as I mentioned, there are two ways to pull an entity from the database, one of which is to use the get method of the Hibernate Session, and the other way is to use the load method. Compare and contrast the following code snippet that invokes the Session's load method to the code snippet that invoked the Session's get method. The difference is subtle, to say the least.

session.beginTransaction();
User user = (User)session.load(User.class, new Long(1));
System.out.println(user.getPassword());
session.getTransaction().commit();

Hibernate load vs. Hibernate get Methods

Well, if you were to compare the load and get methods of the Hibernate Session, you'd think that they looked pretty darned similar; and you'd be correct, but there are subtle and very important differences.

First of all, the get method hits the database as soon as it is called. So, using the Hibernate Session's get method will always trigger a database hit. On the other hand, the load method only hits the database when a particular field of the entity is accessed. So, if we use the load method to retrieve an entity, but we never actually access any of the fields of that entity, we never actually hit the database. Pretty kewl, eh?

Well, actually, as kewl as the load method might sound, it actually triggers more problems than it solves, and here's why. If you initialize a JavaBean instance with a load method call, you can only access the properties of that JavaBean, for the first time, within the transactional context in which it was initialized. If you try to access the various properties of the JavaBean after the transaction that loaded it has been committed, you'll get an exception, a LazyInitializationException, as Hibernate no longer has a valid transactional context to use to hit the database.

So, while this code will work just fine?..

session.beginTransaction();
User user=(User)session.load(User.class, new Long(1));
System.out.println(user.getPassword());
session.getTransaction().commit();

.. this code will fail ?..

session.beginTransaction();
User user=(User)session.load(User.class, new Long(1));
session.getTransaction().commit();
System.out.println(user.getPassword());

.. and generate the following error, telling you that since the transaction was committed, there was no valid Session in which a read transaction against the database could be issued:

org.hibernate.LazyInitializationException: 
could not initialize proxy - no Session

So, the big thing to take away from this is that with the load method, you can't really use your loaded JavaBeans after the transaction has been committed, whereas, with the get method you can, because all of the various properties of a JavaBean retrieved through the get method are initialized right away.

Loading Non-Existent Records

An important scenario under which you need to contrast the load and get methods of the Hibernate Session has to do with what happens when you provide a primary key that doesn't actually exist in the database. Well, with the get method, you are simply returned a null object, which is no big deal.

With the load method, there's also no initial problem when you provide an invalid primary key to the method. From what you can tell, Hibernate appears to hand you back a valid, non-null instance of the class in which you are interested. However, the problems start when you actually try to access a property of that instance - that's where you run into trouble.

Remember how I said the load method doesn't hit the database until a property of the bean is requested? Well, if you've provided a primary key that doesn't exist in your database to the load method, when it does go to the database for the first time, it won't be able to find the non-existent, associated record, and your code will cough up big time. In fact, looking up a field based upon a non-existent primary key with the Hibernate Session's load method triggers the following error:

org.hibernate.ObjectNotFoundException:
No row with the given identifier exists: [User#123]

public Object get (Class clazz, Serializable id) throws HibernateException
--Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance is already associated with the session, return that instance or proxy.)

public Object load (Class theClass,Serializable id) throws HibernateException
--Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists. You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.

-Regurgitated Hibernate API JavaDoc

package com.examscam;
import org.hibernate.*; import com.examscam.model.User;
import org.hibernate.cfg.AnnotationConfiguration;
public class LoadRunner {

  public static void main(String[] args) {
    LoadRunner.callLoad();  LoadRunner.callGet();
  }
  public static void callLoad(){
   AnnotationConfiguration config = 
                  new AnnotationConfiguration();
   config.addAnnotatedClass(User.class);
   SessionFactory factory=   
            config.configure().buildSessionFactory();
   Session session = factory.getCurrentSession();
   session.beginTransaction();
   try {
     User user=
       (User)session.load(User.class,new Long(1));
    System.out.println(user.getPassword ());
   } catch (ObjectNotFoundException e) {
     e.printStackTrace();
   }
   session.getTransaction().commit();
   
/* System.out.println(user.getPassword()); 
   This would fail!!! */
   
  }
  public static void callGet() {
    AnnotationConfiguration config = 
                  new AnnotationConfiguration();
    config.addAnnotatedClass(User.class);
    SessionFactory factory=   
            config.configure().buildSessionFactory();
    Session session = factory.getCurrentSession();
   session.beginTransaction();
   User user=
      (User)session.get(User.class,new Long(1));
    System.out.println(user.getPassword());
    session.getTransaction().commit();
    /* no problem!!!*/
    System.out.println(user.getPassword ()); 
  }
}

When to use get? When to use load?

So, after comparing and contrasting the load and get methods, the natural question that arises is "when do I use the get, and when do I use load?" It's a good question.

For the most part, you'll probably use the get method most often in your code. If you ever want to use the JavaBean that you are retrieving from the database after the database transaction has been committed, you'll want to use the get method, and quite frankly, that tends to be most of the time. For example, if you load a User instance in a Servlet, and you want to pass that instance to a Java Server Page for display purposes, you'd need to use the get method, otherwise, you'd have a LazyInitializationException in your JSP.

On the other hand, if your goal is largely transactional, and you are only going to be accessing the JavaBean of interest within a single unit of work that will pretty much end once the transaction is committed, you'll want to use the load method. For that matter, if you want to ensure that the JavaBean of interest is completely in sync with the database when it is used, you'll want to be using the load method as well, as this will ensure the fields of the JavaBean are being loaded in from the database, and are not just being loaded from the memory of the Java Virtual Machine on which you are running.

Furthermore, the load method may be the method of choice if you know, and are absolutely sure, that the entity you are searching for exists in the database with the primary key you are providing. If you don't know for sure that an entity bearing your primary key exists in the database, you can use the get method, and check to see if the instance that gets returned from the method call returns null.

Hibernate's get and load methods tend to cause plenty of problems for new Hibernate developers. But with a good understanding of the differences between the two, you shouldn't have any problem avoiding LazyInitialization and ObjectNotFound Exceptions.


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