Wednesday, February 22, 2012

Hibernate - Querying

So far we saw how to persist objects to the database.

Now let us see how to get them back.

There are 3 ways to do this in Hibernate:
- To get objects directly by their Id, we can use the Session
- If we want to use SQL-like queries, we can use HQL (we will see this later)
- The preferred way is to use Hibernate Criteria API (we will see this later).

First, let us look at the simplest way - to get Objects by their Id.

Update your UserDAO.java with a method to get the User by Id, like this:
 package org.confucius;   

import org.hibernate.Session;
import org.hibernate.Transaction;

public class UserDAO {

// Getting an object given its Id
public static User getUser (long userId) throws Exception{
User user = null;
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();

try {
user = (User) session.get(User.class, userId);
tx.commit();
}
catch (Exception e){
tx.rollback();
throw e;
}

session.close();
return user;
}


// Persist
public static void persist (User user) throws Exception{
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();

try {
session.persist(user);
tx.commit();

} catch (Exception e){
tx.rollback();
throw e;
}

session.close();
}
}

We have used Session.get() to get the User.

Next, let us update User.java with a toString() method, so we can print the User to console.

Your User.java will now look like this:
 package org.confucius;   

import java.util.Iterator;

public class User {
private long id;
private String firstName;
private String lastName;
private Cart cart;

public void setId(long id) {
this.id = id;
}

public long getId() {
return id;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getFirstName() {
return firstName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getLastName() {
return lastName;
}

public Cart getCart() {
return cart;
}

public void setCart(Cart cart) {
this.cart = cart;
}

public String toString(){
StringBuffer userStr = new StringBuffer();

userStr.append(firstName + " " + lastName + "\n");
userStr.append("Number of Items in Cart = " + cart.getItems().size() + "\n");

for (Iterator<Item> iter = cart.getItems().iterator(); iter.hasNext();)
userStr.append("\tItem = " + iter.next().getName() + "\n");

return userStr.toString();
}

}

Next, update your TestPersistence.java to get a User from the database, like this:
 package org.confucius;   

public class TestPersistence {

public static void main(String[] args) {
try {
User joe = UserDAO.getUser(1);
System.out.println(joe);

} catch (Exception e) {
e.printStackTrace();
}
}
}


Now we need to do a few updates to the Hibernate mappings. We need to turn off the "lazy" loading.

By default, Hibernate will not get the dependencies of an object. It will get them only if and when they are needed (lazy).

Update your User.hbm.xml, like this:
 <?xml version="1.0"?>   
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="org.confucius.User">
<id name="id" type="long">
<generator class="identity" />
</id>
<property name="firstName" type="string" />
<property name="lastName" type="string" />
<many-to-one name="cart" unique="true" cascade="all" lazy="false"/>
</class>
</hibernate-mapping>

Update Cart.hbm.xml, like this:
 <?xml version="1.0"?>   
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="org.confucius.Cart">
<id name="id" type="long">
<generator class="identity" />
</id>
<list name="items" cascade="all" lazy="false">
<key column="cartId"/>
<list-index column="cartListIndex"/>
<one-to-many class="org.confucius.Item"/>
</list>
</class>
</hibernate-mapping>

Finally, we need to update the hibernate.cfg.xml to prevent it from re-creating the tables (we need the data which is in there!).
Like this:
 <?xml version="1.0" encoding="utf-8"?>   
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/confuciusDB</property>
<property name="hibernate.connection.username">confucius</property>
<property name="hibernate.connection.password">changeit</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>

<mapping resource="hibernate-beans/Item.hbm.xml"></mapping>
<mapping resource="hibernate-beans/Cart.hbm.xml"></mapping>
<mapping resource="hibernate-beans/User.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>

R-click on the TestPerssitence.java file in Eclipse Navigator view.
Select Run As--> Java Application

You will see user Joe printed to the console, along with the contents of his cart.

Notice how Hibernate generated all the SQL queries needed to get the User, Cart and Items.

No comments: