Tuesday, February 21, 2012

Hibernate - Dependency Mapping

The real power of Hibernate comes in when classes depend on other classes.

Let us create a class Cart and assign a cart to each user.

Update your Cart.java, like this:
 package org.confucius;  

public class Cart {
private long id;
private int numItems = 0;

public long getId() {
return id;
}

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

public int getNumItems() {
return numItems;
}

public void setNumItems(int numItems) {
this.numItems = numItems;
}
}

In yout /classes/hibernate-beans, create a file 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>
<property name="numItems" type="integer" />
</class>
</hibernate-mapping>

Nothing new so far. We have mapped Cart to Hibernate.

Now, update your hibernate.cfg.xml to make it aware of the Cart mapping, 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">create</property>

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


Now, let us update our User.java, to give users a cart. Like this:
 package org.confucius;   

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;
}
}

Now we update our User.hbm.xml to make it aware of the cart.
 <?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"/>
</class>
</hibernate-mapping>

What have we done here?
Each User has one-to-one relation with a Cart.

There are two ways to specify a one-to-one relation in Hibernate.
Either with a one-to-one map.
Or with a many-to-one map with a "unique= true" constraint.

The second method is more robust, and more widely used. The first method requires IDs to be synchronized and is more sensitive.

We have specified a many-to-one mapping between User and Cart, with the unique=true constraint.

Further we have used the 'cascade' property, which tells Hibernate that whenever we persist User, the cart should be persisted too. Same for update and delete.

Finally, update TestPersistence.java to give a cart to the User, like this:
 package org.confucius;   


public class TestPersistence {

public static void main(String[] args) {
User joe = new User();
joe.setFirstName("Joe");
joe.setLastName("Trumpet");

joe.setCart(new Cart());
joe.getCart().setNumItems(10);

try {
UserDAO.persist(joe);
} catch (Exception e) {
e.printStackTrace();
}
}
}

R-click on TestPersistence.java in Eclipse Navigator view.
Select Run As->Application.

You can now see two tables created in the confuciusDB database - user and cart.
They are linked by a foreign-key, shown in bold below.

 mysql> select * from user;  
+----+-----------+----------+------+
| id | firstName | lastName | cart |
+----+-----------+----------+------+
| 1 | Joe | Trumpet | 1 |
+----+-----------+----------+------+
1 row in set (0.03 sec)

mysql> select * from cart;
+----+----------+
| id | numItems |
+----+----------+
| 1 | 10 |
+----+----------+
1 row in set (0.11 sec)

No comments: