Tuesday, February 21, 2012

Hibernate - List Mapping

To make our example more realistic, let us make Cart contain a List of Items.
Then see how to map this List of Items in Hibernate.

In your /src/org/confucius, create a class Item.java, like this:
 package org.confucius;  

public class Item {
private long id;
private String name;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


Now, update your Cart.java to contain a List of Items. Like this:
 package org.confucius;  

import java.util.List;

public class Cart {
private long id;
private List<Item> items;

public long getId() {
return id;
}

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

public List<Item> getItems() {
return items;
}

public void setItems(List<Item> items) {
this.items = items;
}
}

In your /classes folder, create a file Item.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.Item">
<id name="id" type="long">
<generator class="identity" />
</id>
<property name="name" type="string" />
</class>
</hibernate-mapping>

Nothing new here. We map Item to Hibernate.

Update your hibernate.cfg.xml to make it aware of the Item 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>
<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>

Note that we have added "show-sql" so we can see what Hibernate does behind the scenes.


Now, update your Cart.hbm.xml to map the List of Items, 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">
<key column="cartId"/>
<list-index column="cartListIndex"/>
<one-to-many class="org.confucius.Item"/>
</list>
</class>
</hibernate-mapping>

We have declared a List of Items, and specified the column names for the Key and List-Index ...what these mean will become clear later.

Finally, update TestPersistence.java, like this:
 package org.confucius;   

import java.util.ArrayList;
import java.util.List;


public class TestPersistence {

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

Cart cart = new Cart();
joe.setCart(cart);

List<Item> items = new ArrayList<Item> ();
cart.setItems(items);

Item toothpaste = new Item();
toothpaste.setName("toothpaste");
items.add(toothpaste);

Item diapers = new Item();
diapers.setName("diapers");
items.add(diapers);

Item detergent = new Item();
detergent.setName("detergent");
items.add(detergent);

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


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

Notice that Hibernate displays the SQL queries in the console because we set the show-sql to true.


If you look at the confuciusDB, you will see the three tables - user, cart and item - linked to each other through foreign keys.
 mysql> select * from user;  
+----+-----------+----------+------+
| id | firstName | lastName | cart |
+----+-----------+----------+------+
| 1 | Joe | Trumpet | 1 |
+----+-----------+----------+------+
1 row in set (0.00 sec)

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

mysql> select * from item;
+----+------------+--------+---------------+
| id | name | cartId | cartListIndex |
+----+------------+--------+---------------+
| 1 | toothpaste | 1 | 0 |
| 2 | diapers | 1 | 1 |
| 3 | detergent | 1 | 2 |
+----+------------+--------+---------------+
3 rows in set (0.00 sec)

You will see how the key and list-index columns we specified in Cart mapping are used in the item table.

Note that the cartListIndex columns contains the exact sequence in which each item was added to the items list.

No comments: