Tutorial:

CRUD Operations with Hiberante 3.5 and JPA 2.0 Annotations

By Andrew Tee & Cameron McKenzie

TheServerSide.com

Cameron McKenzie is the author of Hibernate Made Easy and the Editor in Chief of TheServerSide.com

Video Tutorials on Learning Hibernate
Hibernate Made Easy WebSite
Recommended Books for Learning Hibernate
My Similarly Coloured Book on The Simpsons
Check out this updated Tutorial for Spring 3 as well.


Performing CRUD Operations with Hibernate 3.5 and JPA Annotations

This article is a continuation of the following tutorial:
Configuring and Verifying a Hibernate 3.5 and JPA 2.0 Environment

Hibernate & CRUD: Adding Records to the Database

To add records to the database, all you need to do it create an instance of your GameSummary POJO, create an instance of the Hibernate SessionFactory, grab an actual Hibernate Session from that factory (Hibernate Session, not to be confused with the HttpSession), start a transaction, pass your POJO instance to the save method of the Session, and then commit the transaction. It's that simple. Here's how it looks in code (notice that we have commented out the call to the SchemaExport ):


public static void main(String args[]) {
 AnnotationConfiguration config = new AnnotationConfiguration();
 config.addAnnotatedClass(GameSummary.class);
 config.configure();
 //new SchemaExport(config).create(true, true);

 GameSummary gs = new GameSummary();
 gs.setResult("win");

 SessionFactory sessionFactory = config.buildSessionFactory();
 Session session = sessionFactory.getCurrentSession();

 session.beginTransaction();
 session.save(gs);
 session.getTransaction().commit();


}


When you actually run that main method, you see the following console output:

Hibernate: insert into GameSummary (result) values (?)

You can even head to the database and see a new recorded added to the GameSummary table:

Retrieving and Updating Records with Hibernate and JPA

Knowing there's a record in the database with a primary key of one, we can use the get method of the Hibernate Session to pull that instance out of the database, simply by passing in the class type and the primary key as arguments:

GameSummary gs = (GameSummary)session.get(GameSummary.class, new Long(1));
System.out.println(gs.toString());

So long as we keep the Hibernate Session open, we can fiddle around with the properties of the POJO. Any changes or updates we make will get subsequently persisted to the database. So the following code would actually retrieve the entity we originally persisted back from the database, and at the same time, update the result property to indicate a loss.


public static void main(String args[]) {
 AnnotationConfiguration config = new AnnotationConfiguration();
 config.addAnnotatedClass(GameSummary.class);
 config.configure();


 SessionFactory sessionFactory = config.buildSessionFactory();
 Session session = sessionFactory.getCurrentSession();
 session.beginTransaction();

 GameSummary gs = (GameSummary)session.get(GameSummary.class, new Long(1));
 gs.setResult("loss");

  session.getTransaction().commit();
}


Running this main method generates console output indicating that a select query, along with a database update, has occurred.

When we look at the database, we can see that the data has been updated, and the result column now shows a loss.

A Hibernate Query with Multiple Results

The get method of the Hibernate Session will return one entity. If you need to return multiple entities, you create a Hibernate query. Here's how you can use a Hibernate query to grab every record in the database as a list of GameSummary instances:


SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

Query queryResult = session.createQuery("from GameSummary");
java.util.List allSummaries = queryResult.list();

for (int i=0;i<allSummaries.size();i++) {
 GameSummary gs = (GameSummary) allSummaries.get(i);
 System.out.println(gs.toString());
}

session.getTransaction().commit();


We currently only have one record in our database, so this isn't exactly a resource intensive query. However, when we do run this query, we get the following SQL output from the query, along with the toString() output of the single record in our database:

Hibernate: select gamesummar0_.id as id0_, gamesummar0_.result as result0_, gamesummar0_.clientGesture as clientGe3_0_, gamesummar0_.serverGesture as serverGe4_0_, gamesummar0_.date as date0_ from gamesummary gamesummar0_
id: 1 result: win

Deleting Records with Hibernate 3.5 and JPA

To delete a record, we simply obtain the record from Hibernate using the get method; and then pass the obtained object to the delete method of the Hibernate Session, all within an active transaction:


session.beginTransaction();

GameSummary gs = (GameSummary)session.get(GameSummary.class, new Long(1));
session.delete(gs);

session.getTransaction().commit();


This code generates the following SQL, demonstrating that the instance is first loaded, and then deleted, and if you didn't belive the SQL, you could go ahead and look in the database. The record with the primary key of one (1) will have disappeared.

Hibernate: select gamesummar0_.id as id0_0_, gamesummar0_.result as result0_0_ from GameSummary gamesummar0_ where gamesummar0_.id=?
Hibernate: delete from GameSummary where id=?


Pulling it All Together

Here's a completely new class that pulls together all of the incremental little Hibernate persistence that we've coded so far. It just slices each of our CRUD operations into simple methods like save, update and findAll. Our main method then goes through the process of invoking each of these methods, which basically goes through the process of creating, updating, querying and deleting an object. Here's the HibernateCrudRunner:


package com.mcnz.model;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class HibernateCrudRunner {

  public static void main(String[] args) {

    AnnotationConfiguration config = new AnnotationConfiguration();
    config.addAnnotatedClass(GameSummary.class);
    config.configure();
    SessionFactory sessionFactory = config.buildSessionFactory();

    Long entityId = null;
    {
      GameSummary gameSummary = new GameSummary();
      gameSummary.setResult("win");
      System.out.println(gameSummary);
      HibernateCrudRunner.save(sessionFactory, gameSummary);
      entityId = gameSummary.getId();
      System.out.println(gameSummary);
    }

    GameSummary gameSummary
        = HibernateCrudRunner.findByPrimaryKey(sessionFactory, entityId);
    gameSummary.setResult("tie");

    HibernateCrudRunner.update(sessionFactory, gameSummary);

    HibernateCrudRunner.findAll(sessionFactory);

    HibernateCrudRunner.delete(sessionFactory, gameSummary);

    HibernateCrudRunner.findAll(sessionFactory);

  }

  public static void save(SessionFactory sessionFactory, GameSummary gs) {
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();

    session.save(gs);

    session.getTransaction().commit();
  }

  public static void update(SessionFactory sessionFactory, GameSummary gs) {
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();

    session.saveOrUpdate(gs);

    session.getTransaction().commit();
  }

  public static java.util.List findAll(SessionFactory sessionFactory) {
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();

    Query queryResult = session.createQuery("from GameSummary");
    java.util.List allSummaries = queryResult.list();

    for (int i=0;i<allSummaries.size();i++) {
      GameSummary gs = (GameSummary) allSummaries.get(i);
      System.out.println(gs.toString());
    }

    session.getTransaction().commit();
    return allSummaries;
  }

  public static GameSummary findByPrimaryKey(SessionFactory sessionFactory, Long id) {
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();
    GameSummary gs = (GameSummary) session.get(GameSummary.class, id);
    session.getTransaction().commit();
    return gs;
  }

  public static void delete(SessionFactory sessionFactory, GameSummary gs) {
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();
    session.delete(gs);
    session.getTransaction().commit();
  }

}


Looking at the Hibernate 3.5 Crud Runner Output

When the main method of this class is run, we see the following output, which includes the println statement from our code, and the SQL generated by Hibernate:

id: null result: win
Hibernate: insert into gamesummary (result, clientGesture, serverGesture, date) values (?, ?, ?, ?)
id: 5 result: win
Hibernate: select gamesummar0_.id as id0_0_, gamesummar0_.result as result0_0_, gamesummar0_.clientGesture as clientGe3_0_0_, gamesummar0_.serverGesture as serverGe4_0_0_, gamesummar0_.date as date0_0_ from gamesummary gamesummar0_ where gamesummar0_.id=?
Hibernate: update gamesummary set result=?, clientGesture=?, serverGesture=?, date=? where id=?
Hibernate: select gamesummar0_.id as id0_, gamesummar0_.result as result0_, gamesummar0_.clientGesture as clientGe3_0_, gamesummar0_.serverGesture as serverGe4_0_, gamesummar0_.date as date0_ from gamesummary gamesummar0_
id: 1 result: win
id: 5 result: tie
Hibernate: delete from gamesummary where id=?
Hibernate: select gamesummar0_.id as id0_, gamesummar0_.result as result0_, gamesummar0_.clientGesture as clientGe3_0_, gamesummar0_.serverGesture as serverGe4_0_, gamesummar0_.date as date0_ from gamesummary gamesummar0_
id: 1 result: win

Notice that before the GameSummary object is saved, the primary key is null. After the instance is saved, Hibernate has initialized the id, and when we print it out, we get the number 5.

We then update the result from a win to a tie, and then print out all of the content in the database. When we look at the printout for the record with an id of 5, the result has changed to a tie, which demonstrates that our update worked.

Finally, we delete the object with the id of 5, and re-query all of the content in the database. When this happens, only the record with the id of 1 remains - the instance that was created at the beginning of the main method has been deleted.

And that's it. That's how easy it is to do CRUD based operations with the JPA 2.0 compliant edition of Hibernate!


Cameron McKenzie is the author of Hibernate Made Easy and the Editor in Chief of TheServerSide.com

Video Tutorials on Learning Hibernate
Hibernate Made Easy WebSite
Recommended Books for Learning Hibernate
My Similarly Coloured Book on The Simpsons
Check out this updated Tutorial for Spring 3 as well.

20 Jun 2010