Hibernate Mapping

Sang Shin, sang.shin@sun.comwww.javapassion.com/j2ee


In this hands-on lab, you are going to learn various mapping strategies including cadinalities (one to many relationship, many to many relationship), and how class hierarchy is represented in the database tables through inheritance strategies.


Expected duration: 150 minutes

Software Needed

Before you begin, you need to install the following software on your computer. The Hibernate library files  are already included as part of the hands-on lab zip file so you don't have to download Hibernate yourself.


Change Log



Lab Exercises


Exercise 0: Start Java DB (code-named as Derby) database server, create "mydatabase" database (if you have not done so yet)


1. Start the Java DB (Derby) database server if you have not done so yet. 
2. Create "mydatabase" database if you have not done so yet. 
3. Install Hibernate plug-in to the NetBeans IDE as described here.

Exercise 1: Mapping "One-To-Many" Relationship

    In this exercise, you are going to exercise representing "One-To-Many" relationship using various schemes - <set>, <list>, <array>, and <bag> elements in the mapping file.

    1. Open and run "HibernateOneToManyMappingSet" project
    2. Look under the hood of the "HibernateOneToManyMappingSet" project
    3. Open and run "HibernateOneToManyMappingList" project
    4. Look under the hood of the "HibernateOneToManyMappingList" project
    5. Open and run "HibernateOneToManyMappingArray" project
    6. Look under the hood of the "HibernateOneToManyMappingArray" project
    7. Open and run "HibernateOneToManyMappingBag" project
    8. Look under the hood of the "HibernateOneToManyMappingBag" project

(1.1) Open and run "HibernateOneToManyMappingSet" project


1. Open HibernateOneToManyMappingSet NetBeans project. 

2. Build and run HibernateOneToManyMappingSet project.

******** Table: speakers *******
+-------------+-------------+----------------------+----------------------+
|     UID       |   EVENT_ID  |       FIRSTNAME |       LASTNAME     |
+-------------+-------------+----------------------+----------------------+
| 1               | 1                  | Dave                | Smith                  |
| 2               | 1                  | Bill                    | Clinton                |
| 3               | 1                  | Sang                | Shin                    |
| 4               | 2                  | Daniel               | Jones                |
| 5               | 2                 | James                | Gosling              |
+-------------+-------------+----------------------+----------------------+

******** Table: events *******
+-------------+----------------------+------------+-------------+-------------+
|     UID       |         NAME           | START_DATE |   DURATION  | LOCATION_ID |
+-------------+----------------------+------------+-------------+-------------+
| 1               | Java Conference |              0      |             
+-------------+----------------------+------------+-------------+-------------+

Figure-1.11: Result


Trouble-shooting: If you see the following error condition in the Output window, it is highly likely due to the fact the database server is not running.
Solution: Start the database server as described in Exercise 0 above.

15   [main] WARN  org.hibernate.cfg.SettingsFactory  - Could not obtain connection metadata
org.apache.derby.client.am.DisconnectException: java.security.PrivilegedActionException : Error opening socket to server localhost on port 1527 with message : null
        at org.apache.derby.client.net.NetAgent.<init>(Unknown Source)
        at org.apache.derby.client.net.NetConnection.newAgent_(Unknown Source)
        at org.apache.derby.client.am.Connection.<init>(Unknown Source)
        at org.apache.derby.client.net.NetConnection.<init>(Unknown Source)
        at org.apache.derby.jdbc.ClientDriver.connect(Unknown Source)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:154)
        at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:110)
        at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:76)
        at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1933)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1216)
        at HibernateUtil.<clinit>(HibernateUtil.java:26)
        at Main.main(Main.java:9)
Got an exception!

                                                                                                                return to top of the exercise


(1.2) Look under the hood of the "HibernateOneToManyMappingSet" project


1. Study the Main.java.  Pay special attention to the bold-fonted parts. 

import java.util.*;

import org.hibernate.*;
import org.hibernate.criterion.*;

public class Main {
   
   
    public static void main(String[] args) {
       
        // Set up database tables
        HibernateUtil.droptable("drop table EVENTS");
        HibernateUtil.droptable("drop table speakers");
        HibernateUtil.setup("create table EVENTS ( uid int, name VARCHAR(20), start_Date date, duration int, location_id int)");
        HibernateUtil.setup("create table speakers ( uid int, event_id int, firstname VARCHAR(20), lastName VARCHAR(20))");
       
        // Create a Session and Transaction objects
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
       
        // Create an Event object which has one to many relationship
        // with Speaker objects.
        Event event = new Event();
        event.setName("Java Conference");
        event.setSpeakers(new HashSet());
        event.getSpeakers().add(new Speaker("Sang", "Shin"));
        event.getSpeakers().add(new Speaker("Dave", "Smith"));
        event.getSpeakers().add(new Speaker("Bill", "Clinton"));
       
        // Saving an Event object will also save Speaker objects that
        // belong to the Event object.
        session.saveOrUpdate(event);
       
        // Create an Event object which has one to many relationship
        // with Speaker objects.
        Event event2 = new Event();
        event2.setName("Passion Conference");
        event2.setSpeakers(new HashSet());
        event2.getSpeakers().add(new Speaker("James", "Gosling"));
        event2.getSpeakers().add(new Speaker("Daniel", "Jones"));
       
        // Saving an Event object will also save Speaker objects that
        // belong to the Event object.
        session.saveOrUpdate(event);
       
        tx.commit();
        HibernateUtil.closeSession();
        HibernateUtil.sessionFactory.close();
       
        // Display tables
        HibernateUtil.checkData("select * from speakers");
        HibernateUtil.checkData("select * from events");
    }
   
}
Code-1.21:Main.java

2. Study Event.java as shown in Code-1.22 below.  Note that the Event object has a one-to-many relationship with Speaker objects.  The Event class uses Set object to maintain a collection of Speaker objects.

import java.util.Date;
import java.util.Set;

public class Event {
   
    private Long id;
    private String name;
    private Date startDate;
    private int duration;
   
    // Event has one-to-many relationship with Speaker
    private Set speakers;
   
    // Event has one-to-many relationship with Attendee
    private Set attendees;
   
    // Event has one-to-one relationship with Location
    private Location location;
   
    public void setId(Long id) {
        this.id = id;
    }
   
    public Long getId() {
        return id;
    }
   
    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
   
    public Date getStartDate() {
        return startDate;
    }
   
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
   
    public int getDuration() {
        return duration;
    }
   
    public void setDuration(int duration) {
        this.duration = duration;
    }
   
    public Location getLocation() {
        return location;
    }
   
    public void setLocation(Location location) {
        this.location = location;
    }
   
    public void setSpeakers(Set speakers) {
        this.speakers = speakers;
    }
   
    public Set getSpeakers() {
        return speakers;
    }
   
    public Set getAttendees() {
        return attendees;
    }
   
    public void setAttendees(Set attendees) {
        this.attendees = attendees;
    }
   
}
Code-1.22: Event.java

3. Study Speaker.java.

public class Speaker {
   
    private Long id;
    private String firstName;
    private String lastName;
   
    public Speaker() {
    }
   
    public Speaker(String firstName, String lastName) {
        setFirstName(firstName);
        setLastName(lastName);
    }
   
    public Long getId() {
        return id;
    }
   
    public void setId(Long id) {
        this.id = id;
    }
   
    public String getFirstName() {
        return firstName;
    }
   
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
   
    public String getLastName() {
        return lastName;
    }
   
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
   
}
Code-1.23: Speaker.java

4. Study Event.hbm.xml.  This is the mapping file for the Event class. Note that the one-to-many relationship between Event and Speaker classes represented by <set ..> element in the mapping file.  The Event class also has one-to-many relationship with Attendee class as well.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="Event" table="events">
       
        <id name="id" column="uid" type="long" unsaved-value="null">
            <generator class="increment"/>
        </id>
       
        <property name="name" type="string" length="100"/>
       
        <property name="startDate" column="start_date"
                  type="date"/>
        <property name="duration" type="integer"/>
       
        <many-to-one name="location" column="location_id" class="Location"/>
       
        <set name="speakers" cascade="all">
            <key column="event_id"/>
            <one-to-many class="Speaker"/>
        </set>
       
        <set name="attendees" cascade="all">
            <key column="event_id"/>
            <one-to-many class="Attendee"/>
        </set>
       
    </class>
</hibernate-mapping>
Code-1.23: Event.hbm.xml

5. Study Speaker.hbm.xml.  This is the mapping file for the Speaker class.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="Speaker" table="speakers">
        <id name="id" column="uid" type="long">
            <generator class="increment"/>
        </id>
        <property name="firstName" type="string" length="20"/>
        <property name="lastName" type="string" length="20"/>
    </class>
</hibernate-mapping>
Code-1.23: Speaker.hbm.xml


6. Study hibernate.cfg.xml.  This is hibernate configuration file. 

<?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>
       
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="connection.url">jdbc:derby://localhost:1527/mydatabase</property>
        <property name="connection.username">app</property>
        <property name="connection.password">app</property>
       
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
       
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>
       
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
       
        <!-- Mapping files -->
        <mapping resource="Event.hbm.xml"/>
        <mapping resource="Speaker.hbm.xml"/>
        <mapping resource="Attendee.hbm.xml"/>
        <mapping resource="Location.hbm.xml"/>
    </session-factory>
   
</hibernate-configuration>
Code-1.23: hibernate.cfg.xml

                                                                                                              return to top of the exercise

(1.3) Open and run "HibernateOneToManyMappingList" project


In this step, you are going to exercise "rollback" operation.

1. Open HibernateOneToManyMappingList NetBeans project. 

2. Build and run HibernateOneToManyMappingList project.

******** Table: grouptable *******
+-------------+----------------------+
|      ID        |         NAME           |
+-------------+----------------------+
| 1               | Singers                |
| 2               | Politicians            |
+-------------+----------------------+

******** Table: story *******
+-------------+--------------------------------+-------------+-------------+
|      ID        |              INFO                   |     IDX       |  PARENT_ID 
+-------------+--------------------------------+-------------+-------------+
| 1               | Tom Jones                       | 0              | 1               |
| 2               | Beatles                            | 1              | 1               |
| 3               | Elvis                                 | 2              | 1               |
| 4               | Bill Clinton                        | 0              | 2               |
| 5               | Ronald Reagan                | 1              | 2               |
+-------------+--------------------------------+-------------+-------------+
Figure-1.31: Result

                                                                                                              return to top of the exercise


(1.4) Look under the hood of the "HibernateOneToManyMappingList" project


1. Study the Main.java.  Pay special attention to the bold-fonted parts.

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table grouptable");
        HibernateUtil.droptable("drop table story");
        HibernateUtil.setup("create table grouptable (id int,name varchar(20))");
        HibernateUtil.setup("create table story (id int,info varchar(40),idx int,parent_id int)");
       
        // Create Session object
        Session session = HibernateUtil.currentSession();
       
        // Create an Group object which has one to many relationship
        // with Story objects.      
        ArrayList list = new ArrayList();
        list.add(new Story("Tom Jones"));
        list.add(new Story("Beatles"));
        list.add(new Story("Elvis"));
       
        Group sp = new Group("Singers");   
        sp.setStories(list);
       
        ArrayList list2 = new ArrayList();
        list2.add(new Story("Bill Clinton"));
        list2.add(new Story("Ronald Reagan"));
       
        Group sp2 = new Group("Politicians");   
        sp2.setStories(list2);
       
        // Perform save operation in a transactional manner
        Transaction transaction = null;
       
        try {
            transaction = session.beginTransaction();
            session.save(sp);
            session.save(sp2);
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
                throw e;
            }
        }  finally {
            session.close();
        }
       
        // Display tables
        HibernateUtil.checkData("select * from grouptable");
        HibernateUtil.checkData("select * from story");
    }
}
Code-1.41:Main.java

2. Study Group.java.  Note that the Group class has a one-to-many relationship with Story objects through List.

import java.util.*;

public class Group {
   
    private int id;
    private String name;
    private List stories;
   
    public Group(){
    }
   
    public Group(String name) {
        this.name = name;
    }
   
    public void setId(int i) {
        id = i;
    }
   
    public int getId() {
        return id;
    }
   
    public void setName(String n) {
        name = n;
    }
   
    public String getName() {
        return name;
    }
   
    public void setStories(List l) {
        stories = l;
    }
   
    public List getStories() {
        return stories;
    }
}
Code-1.42: Group.java

3. Study Story.java.

import java.util.*;

public class Story {
    private int id;
    private String info;
   
    public Story(){
    }
   
    public Story(String info) {
        this.info = info;
    }
   
    public void setId(int i) {
        id = i;
    }
   
    public int getId() {
        return id;
    }
   
    public void setInfo(String n) {
        info = n;
    }
   
    public String getInfo() {
        return info;
    }
}
Code-1.43: Story.java

4. Study Group.hbm.xml.  Note that the one-to-many relationship between Group and Story objects are represented through <list ..> element.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="Group" table="grouptable">
        <id name="id" unsaved-value="0">
            <generator class="increment" />
        </id>
       
        <list name="stories" cascade="all">
            <key column="parent_id" />
            <index column="idx" />
            <one-to-many class="Story" />
        </list>
        <property name="name" type="string" />
    </class>
   
</hibernate-mapping>
Code-1.44: Group.hbm.xml

5. Study Story.hbm.xml.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="Story" table="story">
        <id name="id" unsaved-value="0">
            <generator class="increment" />
        </id>
        <property name="info" />
    </class>
   
</hibernate-mapping>
Code-1.45: Story.hbm.xml

6. Study hibernate.cfg.xml.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="connection.url">jdbc:derby://localhost:1527/mydatabase</property>
        <property name="connection.username">app</property>
        <property name="connection.password">app</property>
       
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
       
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>
       
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
       
        <!-- Mapping files -->
        <mapping resource="Group.hbm.xml"/>
        <mapping resource="Story.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
Code-1.46: hibernate.cfg.xml

                                                                                                              return to top of the exercise


(1.5) Open and run "HibernateOneToManyMappingArray" project


In this step, you are going to exercise "rollback" operation.

1. Open HibernateOneToManyMappingArray NetBeans project. 

2. Build and run HibernateOneToManyMappingArray project.

******** Table: grouptable *******
+-------------+----------------------+
|      ID        |         NAME           |
+-------------+----------------------+
| 1               | Singers                |
| 2               | Politicians            |
+-------------+----------------------+

******** Table: story *******
+-------------+--------------------------------+-------------+-------------+
|      ID        |              INFO                   |     IDX       |  PARENT_ID 
+-------------+--------------------------------+-------------+-------------+
| 1              | Tom Jones                        | 0               | 1              |
| 2              | Beatles                             | 1               | 1              |
| 3              | Bill Clinton                         | 0              | 2              |
| 4              | Ronald Reagan                 | 1               | 2              |
+-------------+--------------------------------+-------------+-------------+
Figure-1.51: Result

                                                                                                              return to top of the exercise


(1.6) Look under the hood of the "HibernateOneToManyMappingArray" project


1. Study the Main.java.  Pay special attention to the bold-fonted parts.

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table grouptable");
        HibernateUtil.droptable("drop table story");
        HibernateUtil.setup("create table grouptable (id int,name varchar(20))");
        HibernateUtil.setup("create table story (id int,info varchar(40),idx int,parent_id int)");
       
        Session session = HibernateUtil.currentSession();
       
        // Group has an array of Story objects
        Group sp = new Group("Singers");
        sp.setStories(new Story[]{new Story("Tom Jones"), new Story("Beatles")});
        Group sp2 = new Group("Politicians");
        sp2.setStories(new Story[]{new Story("Bill Clinton"), new Story("Ronald Reagan")});
       
        Transaction transaction = null;
       
        try {
            transaction = session.beginTransaction();
            session.save(sp);
            session.save(sp2);
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
                throw e;
            }
        }  finally {
            session.close();
        }
       
        // Display tables
        HibernateUtil.checkData("select * from grouptable");
        HibernateUtil.checkData("select * from story");
    }
}
Code-1.61:Main.java

2. Study Group.java.  Note that the Group class has a one-to-many relationship with Story objects through List.

import java.util.*;

public class Group {
   
    private int id;
    private String name;
   
    // Group object has an array of Story objects
    private Story[] stories;
   
    public void setStories(Story[] l) {
        stories = l;
    }
   
    public Story[] getStories() {
        return stories;
    }
   
    public Group(){
    }
   
    public Group(String name) {
        this.name = name;
    }
   
    public void setId(int i) {
        id = i;
    }
   
    public int getId() {
        return id;
    }
   
    public void setName(String n) {
        name = n;
    }
   
    public String getName() {
        return name;
    }
   
}
Code-1.62: Group.java

3. Study Story.java.

import java.util.*;

public class Story {
   
    private int id;
    private String info;
   
    public Story(){
    }
   
    public Story(String info) {
        this.info = info;
    }
   
    public void setId(int i) {
        id = i;
    }
   
    public int getId() {
        return id;
    }
   
    public void setInfo(String n) {
        info = n;
    }
   
    public String getInfo() {
        return info;
    }
}
Code-1.63: Story.java

4. Study Group.hbm.xml.  Note that the one-to-many relationship between Group and Story objects are represented through <array ..> element.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="Group" table="grouptable">
        <id name="id" unsaved-value="0">
            <generator class="increment"/>
        </id>
       
        <array name="stories" cascade="all">
            <key column="parent_id"/>
            <index column="idx"/>
            <one-to-many class="Story"/>
        </array>
        <property name="name" type="string"/>
    </class>
   
    <class name="Story" table="story">
        <id name="id" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <property name="info"/>
    </class>
   
</hibernate-mapping>
Code-1.64: Group.hbm.xml

                                                                                                                      return to top of the exercise


(1.7) Open and run "HibernateOneToManyMappingBag" project


In this step, you are going to exercise "rollback" operation.

1. Open HibernateOneToManyMappingBag NetBeans project. 

2. Build and run HibernateOneToManyMappingBag project.

******** Table: grouptable *******
+-------------+----------------------+
|      ID        |         NAME           |
+-------------+----------------------+
| 1               | Singers               |
| 2               | Polticians            |
+-------------+----------------------+

******** Table: story *******
+-------------+--------------------------------+-------------+-------------+
|      ID        |              INFO                   |     IDX       |  PARENT_ID  |
+-------------+--------------------------------+-------------+-------------+
| 1               | Tom Jones                       |    1           |
| 2               | Beatles                            |    1           |
| 3               | Ronald Reagan                |    2           |
+-------------+--------------------------------+-------------+-------------+
Figure-1.71: Result

                                                                                                              return to top of the exercise


(1.8) Look under the hood of the "HibernateOneToManyMappingBag" project


1. Study the Main.java.  Pay special attention to the bold-fonted parts.

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table grouptable");
        HibernateUtil.droptable("drop table story");
        HibernateUtil.setup("create table grouptable (id int,name varchar(20))");
        HibernateUtil.setup("create table story (id int,info varchar(40),idx int,parent_id int)");
       
        Session session = HibernateUtil.currentSession();
       
        // Create an Group object which has one to many relationship
        // with Story objects.
        ArrayList list = new ArrayList();
        list.add(new Story("Tom Jones"));
        list.add(new Story("Beatles"));
        Group sp = new Group("Singers");
        sp.setStories(list);
       
        ArrayList list2 = new ArrayList();
        list2.add(new Story("Ronald Reagan"));
        Group sp2 = new Group("Polticians");
        sp2.setStories(list2);
       
        Transaction transaction = null;
       
        try {
            transaction = session.beginTransaction();
            session.save(sp);
            session.save(sp2);
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
                throw e;
            }
        }  finally {
            session.close();
        }
       
        // Display tables
        HibernateUtil.checkData("select * from grouptable");
        HibernateUtil.checkData("select * from story");
    }
}
Code-1.81:Main.java

2. Study Group.java.  Note that the Group class has a one-to-many relationship with Story objects through List.

import java.util.*;

public class Group {
   
    private int id;
    private String name;
    private List stories;
   
    public Group(){
    }
   
    public void setStories(List l) {
        stories = l;
    }
   
    public List getStories() {
        return stories;
    }
   
    public Group(String name) {
        this.name = name;
    }
   
    public void setId(int i) {
        id = i;
    }
   
    public int getId() {
        return id;
    }
   
    public void setName(String n) {
        name = n;
    }
   
    public String getName() {
        return name;
    }
   
}
Code-1.82: Group.java

3. Study Group.hbm.xml.  Note that the one-to-many relationship between Group and Story objects are represented through <list ..> element.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="Group" table="grouptable">
        <id name="id" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <bag name="stories" cascade="all">
            <key column="parent_id"/>
            <one-to-many class="Story"/>
        </bag>
        <property name="name" type="string"/>
    </class>
   
    <class name="Story" table="story">
        <id name="id" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <property name="info"/>
    </class>
   
</hibernate-mapping>
Code-1.83: Group.hbm.xml



                                                                                                              return to top of the exercise

Summary


In this exercise, you have learned how to represent one-to-many relationship between objects through various schemes.


                                                                                                                  return to the top


Exercise 2: Mapping "Many-To-Many" Relationship

In this exercise, you are going to learn how many-to-many relationship is constructed in Hibernate.

  1. Open and run "HibernateManyToManyMapCascadeSaveAndLoad" project
  2. Look under the hood of the "HibernateManyToManyMapCascadeSaveAndLoad" project
  3. Open and run "HibernateManyToManyMapCascadeSaveAndLoadInterface" project
  4. Look under the hood of the "HibernateManyToManyMapCascadeSaveAndLoadInterface" project

(2.1) Open and run "HibernateManyToManyMapCascadeSaveAndLoad" project


1. Open HibernateManyToManyMapCascadeSaveAndLoad NetBeans project. 

2. Build and run HibernateManyToManyMapCascadeSaveAndLoad project.

Event name = JavaOne conference
    Speaker's first name = Sang
    Speaker's last name = Shin
    Speaker id = 1
    Speaker's first name = John
    Speaker's last name = Smith
    Speaker id = 2
    Speaker's first name = Joe
    Speaker's last name = Smith
    Speaker id = 3
Event name = Passion Conference
    Speaker's first name = Diane
    Speaker's last name = Woon
    Speaker id = 4
    Speaker's first name = Sang
    Speaker's last name = Shin
    Speaker id = 5
    Speaker's first name = Shelly
    Speaker's last name = Lumm
    Speaker id = 6


******** Table: m_events *******
+-------------+----------------------+------------+-------------+-------------+
|     UID       |         NAME          | START_DATE |   DURATION  | LOCATION_ID |
+-------------+----------------------+------------+-------------+-------------+
| 1               | JavaOne conference |              0           |             
| 2              | Passion Conference   |              0           |             
+-------------+----------------------+------------+-------------+-------------+

******** Table: m_speakers *******
+-------------+----------------------+----------------------+
|     UID     |       FIRSTNAME      |       LASTNAME       |
+-------------+----------------------+----------------------+
| 1           | Sang                 | Shin                 |
| 2           | John                 | Smith                |
| 3           | Joe                  | Smith                |
| 4           | Diane                | Woon                 |
| 5           | Sang                 | Shin                 |
| 6           | Shelly               | Lumm                 |
+-------------+----------------------+----------------------+

******** Table: event_speakers *******
+-------------+-------------+-------------+
|     ELT     |   EVENT_ID  |  SPEAKER_ID |
+-------------+-------------+-------------+
| 1           | 1                  |             
| 2           | 1                  |             
| 3           | 1                  |             
| 1           |                           1           |
| 1           |                           2           |
| 1           |                           3           |
| 4           | 2                  |             
| 5           | 2                  |             
| 6           | 2                  |             
| 2           |                           4           |
| 2           |                           5           |
| 2           |                           6           |
+-------------+-------------+-------------+
Figure-2.11: Result


                                                                                                             return to top of the exercise


(2.2) look under the hood of the "HibernateManyToManyMapCascadeSaveAndLoad" project


1. Study the Main.java.  Pay special attention to the bold-fonted parts.

import java.util.*;

import org.hibernate.*;
import org.hibernate.criterion.*;

public class Main {
   
   
    public static void main(String[] args) {
       
        // Set up database tables
        HibernateUtil.droptable("drop table m_EVENTS");
        HibernateUtil.droptable("drop table m_speakers");
        HibernateUtil.droptable("drop table event_speakers");
        HibernateUtil.setup("create table m_EVENTS ( uid int, name VARCHAR(20), start_Date date, duration int, location_id int)");
        HibernateUtil.setup("create table m_speakers ( uid int, firstname VARCHAR(20), lastName VARCHAR(20))");
        HibernateUtil.setup("create table event_speakers (elt int, event_id int, speaker_id int)");
       
        // Create Session and Transaction objects
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
       
        // Create the first event with multiple speakers
        EventManyToMany event = new EventManyToMany();
        event.setName("JavaOne conference");
        event.setSpeakers(new HashSet());
        event.getSpeakers().add(new SpeakerManyToMany("John", "Smith", event));
        event.getSpeakers().add(new SpeakerManyToMany("Joe", "Smith", event));
        event.getSpeakers().add(new SpeakerManyToMany("Sang", "Shin", event));
       
        // Save event object
        session.save(event);
       
        // Create the second event with multiple speakers
        EventManyToMany event2 = new EventManyToMany();
        event2.setName("Passion Conference");
        event2.setSpeakers(new HashSet());
        event2.getSpeakers().add(new SpeakerManyToMany("Sang", "Shin", event2));
        event2.getSpeakers().add(new SpeakerManyToMany("Shelly", "Lumm", event2));
        event2.getSpeakers().add(new SpeakerManyToMany("Diane", "Woon", event2));
       
        // Save event object
        session.save(event2);
       
        // Load an Event object and see Speaker objects get also read
        System.out.println("Event name = " + event.getName());
        event = (EventManyToMany) session.load(EventManyToMany.class, event.getId());
        Set speakers = event.getSpeakers();
       
        for (Iterator i = speakers.iterator(); i.hasNext();) {
            SpeakerManyToMany speaker = (SpeakerManyToMany) i.next();
            System.out.println("    Speaker's first name = " + speaker.getFirstName());
            System.out.println("    Speaker's last name = " + speaker.getLastName());
            System.out.println("    Speaker id = " + speaker.getId());
        }
       
        System.out.println("Event name = " + event2.getName());
        event2 = (EventManyToMany) session.load(EventManyToMany.class, event2.getId());
        Set speakers2 = event2.getSpeakers();
       
        for (Iterator i = speakers2.iterator(); i.hasNext();) {
            SpeakerManyToMany speaker2 = (SpeakerManyToMany) i.next();
            System.out.println("    Speaker's first name = " + speaker2.getFirstName());
            System.out.println("    Speaker's last name = " + speaker2.getLastName());
            System.out.println("    Speaker id = " + speaker2.getId());
        }
       
        tx.commit();
        HibernateUtil.closeSession();
       
        HibernateUtil.sessionFactory.close();
       
        // Display tables
        HibernateUtil.checkData("select * from m_events");
        HibernateUtil.checkData("select * from m_speakers");
        HibernateUtil.checkData("select * from event_speakers");
    }
   
}
Code-2.21: Main.java

2. Study EventManyToMany.java.  Note that this class has a many-to-many relationship with Speaker class through Set interface.

import java.util.Date;
import java.util.Set;

public class EventManyToMany {
   
    private Long id;
    private String name;
    private Date startDate;
    private int duration;
    private Set speakers;
    private Set attendees;
    private LocationManyToMany location;
   
    public void setId(Long id) {
        this.id = id;
    }
   
    public Long getId() {
        return id;
    }
   
    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
   
    public Date getStartDate() {
        return startDate;
    }
   
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
   
    public int getDuration() {
        return duration;
    }
   
    public void setDuration(int duration) {
        this.duration = duration;
    }
   
    public LocationManyToMany getLocation() {
        return location;
    }
   
    public void setLocation(LocationManyToMany location) {
        this.location = location;
    }
   
    public void setSpeakers(Set speakers) {
        this.speakers = speakers;
    }
   
    public Set getSpeakers() {
        return speakers;
    }
   
    public Set getAttendees() {
        return attendees;
    }
   
    public void setAttendees(Set attendees) {
        this.attendees = attendees;
    }
   
}
Code-2.22: EventManyToMany.java

3. Study the SpeakerManyToMany.java.  Note that this class has many-to-many relationship with Event class through Set interface.

import java.util.Set;
import java.util.HashSet;

public class SpeakerManyToMany {
   
    private Long id;
    private String firstName;
    private String lastName;
    private Set events;
   
    public SpeakerManyToMany() {
    }
   
    public SpeakerManyToMany(String firstName, String lastName) {
        setFirstName(firstName);
        setLastName(lastName);
    }
   
    public SpeakerManyToMany(String firstName, String lastName, EventManyToMany event) {
        this(firstName, lastName);
        addEvent(event);
    }
   
    public Long getId() {
        return id;
    }
   
    public void setId(Long id) {
        this.id = id;
    }
   
    public String getFirstName() {
        return firstName;
    }
   
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
   
    public String getLastName() {
        return lastName;
    }
   
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
   
    public Set getEvents() {
        return this.events;
    }
   
    public void setEvents(Set events) {
        this.events = events;
    }
   
    private void addEvent(EventManyToMany event) {
        if (events == null) {
            events = new HashSet();
        }
        events.add(event);
    }
}
Code-2.23: SpeakerManyToMany.java

4. Study EventManyToMany.hbm.xml.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="EventManyToMany" table="m_events">
        <id name="id" column="uid" type="long" unsaved-value="null">
            <generator class="increment"/>
        </id>
       
        <property name="name" type="string" length="100"/>
        <property name="startDate" column="start_date"
                  type="date"/>
        <property name="duration" type="integer"/>
       
        <many-to-one name="location" column="location_id"
                     class="LocationManyToMany"/>
       
        <set name="speakers" table="event_speakers" cascade="all">
            <key column="event_id"/>
            <many-to-many class="SpeakerManyToMany"/>
        </set>

    </class>
   
</hibernate-mapping>
Code-2.24: EventManyToMany.hbm.xml

5. Study SpeakerManyToMany.hbm.xml.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="SpeakerManyToMany" table="m_speakers">
        <id name="id" column="uid" type="long">
            <generator class="increment"/>
        </id>
        <property name="firstName" type="string" length="20"/>
        <property name="lastName" type="string" length="20"/>
       
        <set name="events" table="event_speakers" cascade="all">
            <key column="speaker_id"/>
            <many-to-many class="EventManyToMany"/>
        </set>
       
    </class>
   
</hibernate-mapping>
Code-2.25: SpeakerManyToMany.hbm.xml

6. Study hibernate.cfg.xml.

<?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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="connection.url">jdbc:derby://localhost:1527/mydatabase</property>
        <property name="connection.username">app</property>
        <property name="connection.password">app</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>

        <!-- Mapping files -->
        <mapping resource="EventManyToMany.hbm.xml"/>
        <mapping resource="SpeakerManyToMany.hbm.xml"/>
        <mapping resource="LocationManyToMany.hbm.xml"/>
    </session-factory>

</hibernate-configuration>
Code-2.26: hibernate.cfg.xml
                                                                                                              return to top of the exercise




Summary

In this exercise,  you have learned how to to map many-to-many relationship.

                                                                                                                        return to the top


Exercise 3: Mapping "HashMap" Relationship


In this exercise, you are going to learn how to map a HashMap.


(3.1) Build and run"HibernateCollectionMappingMap" project


1. Open HibernateCollectionMappingMap NetBeans project. 

2. Build and run HibernateCollectionMappingMap project.

car property = null
tv property = samsung

******** Table: supportproperty *******
+-------------+----------------------+
|      ID        |         NAME           |
+-------------+----------------------+
| 1               | MyProperties       |
| 2               | YourProperties    |
+-------------+----------------------+

******** Table: properties *******
+-------------+----------------------+----------------------+
|      ID        |     PROPERTY_NAME    |    PROPERTY_VALUE    |
+-------------+----------------------+----------------------+
| 1               | car                      | ford                      |
| 1               | house                 | lexington              |
| 2               | tv                        | samsung              |
| 2               | house                 | lexington              |
+-------------+----------------------+----------------------+
Figure-3.11: Result
                                                                                                              return to top of the exercise


(3.2) look under the hood of the "HibernateCollectionMappingMap" project


1. Study the Main.java. (Code-3.21 below)  Pay special attention to the bold-fonted parts.

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table supportproperty");
        HibernateUtil.droptable("drop table properties");
        HibernateUtil.setup("create table supportproperty (id int,name varchar(20))");
        HibernateUtil.setup("create table properties (id int,property_name VARCHAR(20),property_value varchar(20))");
       
        // Create Session and Transaction object
        Session session = HibernateUtil.currentSession();
        Transaction transaction = null;
       
        Map p2 = null;
        try {
            transaction = session.beginTransaction();
           
            // Create Domain object, SupportProperty object has a Map
            // object.
            SupportProperty sp = new SupportProperty();
            sp.setName("MyProperties");
           
            HashMap h = new HashMap();
            h.put("car", "ford");
            h.put("house", "lexington");
            sp.setProperties(h);
           
            session.save(sp);
           
            // Create another object instance
            SupportProperty sp2 = new SupportProperty();
            sp2.setName("YourProperties");
            HashMap h2 = new HashMap();
            h2.put("tv", "samsung");
            h2.put("house", "lexington");
            sp2.setProperties(h2);
           
            session.save(sp2);
           
            SupportProperty sp3 = (SupportProperty)session.load(SupportProperty.class, new Integer(sp.getId()));
            p2 = sp2.getProperties();
           
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
                throw e;
            }
        }  finally {
            session.close();
        }
       
        System.out.println("car property = " + p2.get("car"));
        System.out.println("tv property = " + p2.get("tv"));
       
        // Display tables
        HibernateUtil.checkData("select * from supportproperty");
        HibernateUtil.checkData("select * from properties");
    }
}
Code-3.21: Main.java

2. Study SupportProperty.java.

import java.util.*;

public class SupportProperty {
   
    private int id;
    private String name;
    private Map properties;
   
    public SupportProperty() {
    }
   
    public void setId(int i) {
        id = i;
    }
   
    public int getId() {
        return id;
    }
   
    public void setName(String s) {
        name = s;
    }
   
    public String getName() {
        return name;
    }
   
    public void setProperties(Map m) {
        properties = m;
    }
   
    public Map getProperties() {
        return properties;
    }
}
Code-3.22: SupportProperty.java

3. Study SupportProperty.hbm.xml. (Code-3.23 below) 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="SupportProperty" table="supportproperty">
        <id name="id">
            <generator class="increment"/>
        </id>
       
        <map name="properties">
            <key column="id"/>
            <index column="property_name" type="string"/>
            <element column="property_value" type="string"/>
        </map>
       
        <property name="name" type="string"/>
    </class>
   
</hibernate-mapping>
Code-3.23: SupportProperty.hbm.xml

                                                                                                                        return to top of the exercise


Summary


In this exercise, you have learned how to map Map relationship.


                                                                                                                    return to the top



Exercise 4: Mapping Object Inheritance


In this exercise, you are going to learn how to map object inheritance relationship using different strategies.
  1. Build and run "HibernateClassHierarchyMappingTablePerClassHierarchy" project
  2. Look under the hood of the "HibernateClassHierarchyMappingTablePerClassHierarchy" project
  3. Build and run "HibernateClassHierarchyMappingTablePerSubclass" project
  4. Look under the hood of the "HibernateClassHierarchyMappingTablePerSubclass" project

(4.1) Build and run "HibernateClassHierarchyMappingTablePerClassHierarchy" project


1. Open HibernateClassHierarchyMappingTablePerClassHierarchy NetBeans project. 

2. Build and run HibernateClassHierarchyMappingTablePerClassHierarchy project.

******** Table: Book *******
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+
|      ID        |         TITLE           |        ARTIST          | PURCHASEDATE |          COST    |      NEWFEATURES    
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+
| 1               | Book                   | R                          | 2007-04-24        | 9.99              |       
| 2               | sBook                 | R                          | 2007-04-24        | 9.99              | W                  
| 3               | IBook                  | R                          | 2007-04-24        | 9.99              |                                     
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+
Figure-4.11: Result
                                                                                                              return to top of the exercise


(4.2) look under the hood of the "HibernateClassHierarchyMappingTablePerClassHierarchy" project


1. Study the Main.java. (Code-4.21 below) Pay special attention to the bold-fonted parts. 

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table Book");
        HibernateUtil.setup("create table Book(id int,title varchar(20),artist varchar(20),purchasedate date,cost double,newfeatures varchar(20),languages varchar(20),region int,Book_type varchar(20))");
       
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
       
        Book cd = new Book("Book", "R", new Date(), 9.99);
        SpecialEditionBook secd = new SpecialEditionBook("sBook", "R", new Date(), 9.99, "W");
        InternationalBook icd = new InternationalBook("IBook", "R", new Date(), 9.99, "S", 4);
       
        session.save(cd);
        session.save(secd);
        session.save(icd);
       
        tx.commit();
       
        session.close();
       
        // Display tables
        HibernateUtil.checkData("select * from Book");
    }
}
Code-4.21: Main.java

2. Study Book.java.  The Book class is the parent class of the SpecialEditionBook and InternationalBook classes.

import java.io.*;
import java.util.*;

public class Book {
    int id;
    String title;
    String artist;
    Date    purchaseDate;
    double cost;
   
    public Book() {
    }
   
    public Book(String title, String artist, Date purchaseDate, double cost) {
        this.title = title;
        this.artist = artist;
        this.purchaseDate = purchaseDate;
        this.cost = cost;
    }
   
    public void setId(int id) {
        this.id = id;
    }
   
    public int getId(){
        return id;
    }
   
    public void setTitle(String title) {
        this.title = title;
    }
   
    public String getTitle() {
        return title;
    }
   
    public void setArtist(String artist) {
        this.artist = artist;
    }
   
    public String getArtist() {
        return artist;
    }
   
    public void setPurchasedate(Date purchaseDate) {
        this.purchaseDate = purchaseDate;
    }
   
    public Date getPurchasedate() {
        return purchaseDate;
    }
   
    public void setCost(double cost) {
        this.cost = cost;
    }
   
    public double getCost() {
        return cost;
    }
}
Code-4.22: Book.java

3. Study InternationalBook.java.  The InternationalBook class is a child class of Book class.  Note that the InternationalBook class has its own fields - languages and region fields.

import java.util.*;

public class InternationalBook extends Book {
   
    private String languages;
    private int region;
   
    public InternationalBook() {
    }
   
    public InternationalBook(String title, String artist, Date purchaseDate, double cost, String language, int region) {
        super(title, artist, purchaseDate, cost);
       
        languages = language;
        this.region = region;
    }
   
    public void setLanguages(String s) {
        languages = s;
    }
   
    public String getLanguages() {
        return languages;
    }
   
    public void setRegion(int i) {
        region = i;
    }
   
    public int getRegion() {
        return region;
    }
}
Code-4.23: InternationalBook.java

4. Study SpecialEditionBook.java.  The SpecialEditionBook class is a child class of Book class.  Note that the SpecialEditionBook class has its own field - newfeatures field.

import java.util.*;

public class SpecialEditionBook extends Book {
   
    private String newfeatures;
   
    public SpecialEditionBook() {
    }
   
    public SpecialEditionBook(String title, String artist, Date purchaseDate, double cost, String features) {
        super(title, artist, purchaseDate, cost);
       
        newfeatures = features;
    }
   
    public void setNewfeatures(String s) {
        newfeatures = s;
    }
   
    public String getNewfeatures() {
        return newfeatures;
    }
}
Code-4.24: SpecialEditionBook.java

5. Study Book.hbm.xml.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="Book" table="Book" discriminator-value="Book">
        <id name="id" type="integer"  unsaved-value="0">
            <generator class="increment"/>
        </id>
       
        <discriminator column="Book_type" type= "string"/>
       
        <property name="title"/>
        <property name="artist"/>
        <property name="purchasedate" type="date"/>
        <property name="cost" type="double"/>
       
    </class>
   
</hibernate-mapping>
Code-4.25: Book.hbm.xml

6. Study InternationalBook.hbm.xml.  Note that it uses <subclass ..> element along with extends attribute.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <subclass name="InternationalBook"
              extends="Book"
              discriminator-value="InternationalBook">
        <property name="languages" />
        <property name="region" />
    </subclass>
   
</hibernate-mapping>
Code-4.26: InternationalBook.hbm.xml

7. Study SpecialEditionBook.hbm.xml.  Note that it uses <subclass ..> element along with extends attribute.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <subclass name="SpecialEditionBook"
              extends="Book"
              discriminator-value="SpecialEditionBook">
        <property name="newfeatures" type="string" />
    </subclass>
   
</hibernate-mapping>
Code-4.27: SpecialEditionBook.hbm.xml

8. Study the hibernate.cfg.xml.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">
            org.apache.derby.jdbc.ClientDriver
        </property>
        <property name="connection.url">
            jdbc:derby://localhost:1527/mydatabase
        </property>
        <property name="connection.username">app</property>
        <property name="connection.password">app</property>
       
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
       
        <!-- SQL dialect -->
        <property name="dialect">
            org.hibernate.dialect.DerbyDialect
        </property>
       
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
       
        <!-- Mapping files -->
        <mapping resource="Book.hbm.xml" />
        <mapping resource="InternationalBook.hbm.xml" />
        <mapping resource="SpecialEditionBook.hbm.xml" />
    </session-factory>
</hibernate-configuration>
Code-4.28: hibernate.cfg.xml


                                                                                                                        return to top of the exercise


(4.3) Build and run "HibernateClassHierarchyMappingTablePerSubclass" project


1. Open HibernateClassHierarchyMappingTablePerSubclass NetBeans project. 

2.  Build and run HibernateClassHierarchyMappingTablePerSubclass project.

******** Table: Book *******
+-------------+----------------------+----------------------+--------------+------------------------+
|      ID        |         TITLE           |        ARTIST          | PURCHASEDATE |          COST        
+-------------+----------------------+----------------------+--------------+------------------------+
| 1              | Book                     | R                         | 2007-04-24        | 9.99                  
| 2              | sBook                   | R                         | 2007-04-24        | 9.99                  
| 3              | IBook                    | R                         | 2007-04-24        | 9.99                  
+-------------+----------------------+----------------------+--------------+------------------------+

******** Table: SpecialEditionBook *******
+-------------+--------------------------------+
|      ID        |           NEWFEATURES       |
+-------------+--------------------------------+
| 2              | W                                     |
+-------------+--------------------------------+

******** Table: InternationalBook *******
+-------------+--------------------------------+-------------+
|      ID        |            LANGUAGES           |    REGION  
+-------------+--------------------------------+-------------+
| 3               | S                                      | 4              |
+-------------+--------------------------------+-------------+
Figure-4.31: Result
                                                                                                              return to top of the exercise


(4.4) look under the hood of the "HibernateClassHierarchyMappingTablePerSubclass" project


1. Study the Main.java. (Code-4.41 below)  Pay special attention to the bold-fonted parts.  Note that since you are going to use "assigned" as a way of creating keys, you have to provide the key values yourself through setId() method.

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table Book");
        HibernateUtil.droptable("drop table SpecialEditionBook");
        HibernateUtil.droptable("drop table InternationalBook");
        HibernateUtil.setup("create table Book(id int,title varchar(20),artist varchar(20),purchasedate date,cost double)");
        HibernateUtil.setup("create table SpecialEditionBook(id int,newfeatures varchar(40))");
        HibernateUtil.setup("create table InternationalBook(id int,languages varchar(40),region int)");
       
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
       
        // Create objects which have inheritance relationship
        Book cd = new Book("Book", "R", new Date(), 9.99);
        SpecialEditionBook secd = new SpecialEditionBook("sBook", "R",
                new Date(), 9.99, "W");
        InternationalBook icd = new InternationalBook("IBook", "R", new Date(),
                9.99, "S", 4);
       
        session.save(cd);
        session.save(secd);
        session.save(icd);
        tx.commit();
       
        session.flush();
        session.close();
       
        // Display tables
        HibernateUtil.checkData("select * from Book");
        HibernateUtil.checkData("select * from SpecialEditionBook");
        HibernateUtil.checkData("select * from InternationalBook");
    }
}
Code-4.41: Main.java

2. Study Book.java.  The Book class is the parent class of the SpecialEditionBook and InternationalBook classes.

import java.io.*;
import java.util.*;

public class Book {
    int id;
    String title;
    String artist;
    Date    purchaseDate;
    double cost;
   
    public Book() {
    }
   
    public Book(String title, String artist, Date purchaseDate, double cost) {
        this.title = title;
        this.artist = artist;
        this.purchaseDate = purchaseDate;
        this.cost = cost;
    }
   
    public void setId(int id) {
        this.id = id;
    }
   
    public int getId(){
        return id;
    }
   
    public void setTitle(String title) {
        this.title = title;
    }
   
    public String getTitle() {
        return title;
    }
   
    public void setArtist(String artist) {
        this.artist = artist;
    }
   
    public String getArtist() {
        return artist;
    }
   
    public void setPurchasedate(Date purchaseDate) {
        this.purchaseDate = purchaseDate;
    }
   
    public Date getPurchasedate() {
        return purchaseDate;
    }
   
    public void setCost(double cost) {
        this.cost = cost;
    }
   
    public double getCost() {
        return cost;
    }
}
Code-4.42: Book.java

3. Study InternationalBook.java.  The InternationalBook class is a child class of Book class.  Note that the InternationalBook class has its own fields - languages and region fields.

import java.util.*;

public class InternationalBook extends Book {
   
    private String languages;
    private int region;
   
    public InternationalBook() {
    }
   
    public InternationalBook(String title, String artist, Date purchaseDate, double cost, String language, int region) {
        super(title, artist, purchaseDate, cost);
       
        languages = language;
        this.region = region;
    }
   
    public void setLanguages(String s) {
        languages = s;
    }
   
    public String getLanguages() {
        return languages;
    }
   
    public void setRegion(int i) {
        region = i;
    }
   
    public int getRegion() {
        return region;
    }
}
Code-4.43: InternationalBook.java

4. Study SpecialEditionBook.java.  The SpecialEditionBook class is a child class of Book class.  Note that the SpecialEditionBook class has its own field - newfeatures field.

import java.util.*;

public class SpecialEditionBook extends Book {
   
    private String newfeatures;
   
    public SpecialEditionBook() {
    }
   
    public SpecialEditionBook(String title, String artist, Date purchaseDate, double cost, String features) {
        super(title, artist, purchaseDate, cost);
       
        newfeatures = features;
    }
   
    public void setNewfeatures(String s) {
        newfeatures = s;
    }
   
    public String getNewfeatures() {
        return newfeatures;
    }
}
Code-4.44: SpecialEditionBook.java

5. Study Book.hbm.xml.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="Book" table="Book">
        <id name="id" type="integer" unsaved-value="0">
            <generator class="increment" />
        </id>
       
        <property name="title" />
        <property name="artist" />
        <property name="purchasedate" type="date" />
        <property name="cost" type="double" />
       
    </class>
</hibernate-mapping>
Code-4.45: Book.hbm.xml

6. Study InternationalBook.hbm.xml.  Note that it uses <joined-subclass ..> element along with extends attribute.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <joined-subclass name="InternationalBook"
              extends="Book" table="InternationalBook">
        <key column="id" />
        <property name="languages" />
        <property name="region" />
    </joined-subclass>
   
</hibernate-mapping>
Code-4.46: InternationalBook.hbm.xml

7. Study SpecialEditionBook.hbm.xml.  Note that it uses <joined-subclass ..> element along with extends attribute.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <joined-subclass name="SpecialEditionBook" extends="Book"
              table="SpecialEditionBook">
        <key column="id" />
        <property name="newfeatures" type="string" />
    </joined-subclass>
   
</hibernate-mapping>
Code-4.47: SpecialEditionBook.hbm.xml

8. Study the hibernate.cfg.xml.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">
            org.apache.derby.jdbc.ClientDriver
        </property>
        <property name="connection.url">
            jdbc:derby://localhost:1527/mydatabase
        </property>
        <property name="connection.username">app</property>
        <property name="connection.password">app</property>
       
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
       
        <!-- SQL dialect -->
        <property name="dialect">
            org.hibernate.dialect.DerbyDialect
        </property>
       
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
       
        <!-- Mapping files -->
        <mapping resource="Book.hbm.xml" />
        <mapping resource="InternationalBook.hbm.xml" />
        <mapping resource="SpecialEditionBook.hbm.xml" />
    </session-factory>
</hibernate-configuration>
Code-4.48: hibernate.cfg.xml


                                                                                                                        return to top of the exercise


(4.5) Build and run "HibernateClassHierarchyMappingTablePerConcreteClass" project


1. Open HibernateClassHierarchyMappingTablePerConcreteClass NetBeans project. 

2. Build and run HibernateClassHierarchyMappingTablePerConcreteClass project.

******** Table: Book *******
+-------------+----------------------+----------------------+--------------+------------------------+
|      ID        |         TITLE           |        ARTIST          | PURCHASEDATE |          COST          |
+-------------+----------------------+----------------------+--------------+------------------------+
| 1               | Book                    | R                         | 2007-04-24       | 9.99                   |
+-------------+----------------------+----------------------+--------------+------------------------+

******** Table: SpecialEditionBook *******
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+
|      ID        |         TITLE           |        ARTIST          | PURCHASEDATE |          COST    |      NEWFEATURES    
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+
| 1              | sBook                   | R                         | 2007-04-24        | 9.99              | W                         |
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+

******** Table: InternationalBook *******
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+-------------+
|      ID        |         TITLE           |        ARTIST          | PURCHASEDATE |          COST    |       LANGUAGES   |    REGION |
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+-------------+
| 1               | IBook                  | R                          | 2007-04-24       | 9.99               | S                         | 4               |
| 2               | IBook                  | R                          | 2007-04-24       | 100.9             | T                         | 3               |
+-------------+----------------------+----------------------+--------------+------------------------+----------------------+-------------+
Figure-4.51: Result
                                                                                                              return to top of the exercise


(4.6) look under the hood of the "HibernateClassHierarchyMappingTablePerConcreteClass" project


1. Study the Main.java. (Code-4.41 below)  Pay special attention to the bold-fonted parts.  Note that since you are going to use "assigned" as a way of creating keys, you have to provide the key values yourself through setId() method.

import java.io.Serializable;
import java.util.*;

import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.criterion.*;
import org.hibernate.event.*;
import org.hibernate.event.def.*;

public class Main {
   
    public static void main(String[] args) throws Exception {
       
        // Set up database tables
        HibernateUtil.droptable("drop table Book");
        HibernateUtil.droptable("drop table SpecialEditionBook");
        HibernateUtil.droptable("drop table InternationalBook");
        HibernateUtil.setup("create table Book(id int,title varchar(20),artist varchar(20),purchasedate date,cost double)");
        HibernateUtil.setup("create table SpecialEditionBook(id int,title varchar(20),artist varchar(20),purchasedate date,cost double,newfeatures varchar(20))");
        HibernateUtil.setup("create table InternationalBook(id int,title varchar(20),artist varchar(20),purchasedate date,cost double,languages varchar(20),region int)");
           
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
       
        Book cd = new Book("Book", "R", new Date(), 9.99);
        SpecialEditionBook secd = new SpecialEditionBook("sBook", "R",
                new Date(), 9.99, "W");
        InternationalBook icd = new InternationalBook("IBook", "R", new Date(),
                9.99, "S", 4);
       
        session.save(cd);
        session.save(secd);
        session.save(icd);
       
        icd = new InternationalBook("IBook", "R", new Date(), 100.9, "T", 3);
        session.save(icd);
       
        tx.commit();
       
        session.close();
       
        // Display tables
        HibernateUtil.checkData("select * from Book");
        HibernateUtil.checkData("select * from SpecialEditionBook");
        HibernateUtil.checkData("select * from InternationalBook");
    }
}
Code-4.61: Main.java

2. Study Book.java.  The Book class is the parent class of the SpecialEditionBook and InternationalBook classes.

import java.io.*;
import java.util.*;

public class Book {
    int id;
    String title;
    String artist;
    Date    purchaseDate;
    double cost;
   
    public Book() {
    }
   
    public Book(String title, String artist, Date purchaseDate, double cost) {
        this.title = title;
        this.artist = artist;
        this.purchaseDate = purchaseDate;
        this.cost = cost;
    }
   
    public void setId(int id) {
        this.id = id;
    }
   
    public int getId(){
        return id;
    }
   
    public void setTitle(String title) {
        this.title = title;
    }
   
    public String getTitle() {
        return title;
    }
   
    public void setArtist(String artist) {
        this.artist = artist;
    }
   
    public String getArtist() {
        return artist;
    }
   
    public void setPurchasedate(Date purchaseDate) {
        this.purchaseDate = purchaseDate;
    }
   
    public Date getPurchasedate() {
        return purchaseDate;
    }
   
    public void setCost(double cost) {
        this.cost = cost;
    }
   
    public double getCost() {
        return cost;
    }
}
Code-4.62: Book.java

3. Study InternationalBook.java.  The InternationalBook class is a child class of Book class.  Note that the InternationalBook class has its own fields - languages and region fields.

import java.util.*;

public class InternationalBook extends Book {
   
    private String languages;
    private int region;
   
    public InternationalBook() {
    }
   
    public InternationalBook(String title, String artist, Date purchaseDate, double cost, String language, int region) {
        super(title, artist, purchaseDate, cost);
       
        languages = language;
        this.region = region;
    }
   
    public void setLanguages(String s) {
        languages = s;
    }
   
    public String getLanguages() {
        return languages;
    }
   
    public void setRegion(int i) {
        region = i;
    }
   
    public int getRegion() {
        return region;
    }
}
Code-4.63: InternationalBook.java

4. Study SpecialEditionBook.java.  The SpecialEditionBook class is a child class of Book class.  Note that the SpecialEditionBook class has its own field - newfeatures field.

import java.util.*;

public class SpecialEditionBook extends Book {
   
    private String newfeatures;
   
    public SpecialEditionBook() {
    }
   
    public SpecialEditionBook(String title, String artist, Date purchaseDate, double cost, String features) {
        super(title, artist, purchaseDate, cost);
       
        newfeatures = features;
    }
   
    public void setNewfeatures(String s) {
        newfeatures = s;
    }
   
    public String getNewfeatures() {
        return newfeatures;
    }
}
Code-4.64: SpecialEditionBook.java

5. Study Book.hbm.xml.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class name="Book" table="Book" discriminator-value="Book">
        <id name="id" type="integer" unsaved-value="0">
            <generator  class="increment"/>
        </id>
        <property name="title"/>
        <property name="artist"/>
        <property name="purchasedate" type="date"/>
        <property name="cost" type="double"/>
    </class>
   
</hibernate-mapping>
Code-4.65: Book.hbm.xml

6. Study InternationalBook.hbm.xml.  Note that it uses <joined-subclass ..> element along with extends attribute.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class  name="InternationalBook" table="InternationalBook">
        <id name="id" type="integer" unsaved-value="0">
            <generator  class="increment"/>
        </id>
        <property name="title"/>
        <property name="artist"/>
        <property name="purchasedate" type="date"/>
        <property name="cost" type="double"/>
        <property name="languages"/>
        <property name="region"/>
    </class> 
   
</hibernate-mapping>
Code-4.66: InternationalBook.hbm.xml

7. Study SpecialEditionBook.hbm.xml.  Note that it uses <joined-subclass ..> element along with extends attribute.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
    <class  name="SpecialEditionBook" table="SpecialEditionBook">
        <id name="id" type="integer" unsaved-value="0">
            <generator  class="increment"/>
        </id>
        <property name="title"/>
        <property name="artist"/>
        <property name="purchasedate" type="date"/>
        <property name="cost" type="double"/>
        <property name="newfeatures" type="string"/>
    </class>
   
</hibernate-mapping>
Code-4.67: SpecialEditionBook.hbm.xml

8. Study the hibernate.cfg.xml.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">
            org.apache.derby.jdbc.ClientDriver
        </property>
        <property name="connection.url">
            jdbc:derby://localhost:1527/mydatabase
        </property>
        <property name="connection.username">app</property>
        <property name="connection.password">app</property>
       
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
       
        <!-- SQL dialect -->
        <property name="dialect">
            org.hibernate.dialect.DerbyDialect
        </property>
       
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
       
        <!-- Mapping files -->
        <mapping resource="Book.hbm.xml" />
        <mapping resource="InternationalBook.hbm.xml" />
        <mapping resource="SpecialEditionBook.hbm.xml" />
    </session-factory>
</hibernate-configuration>
Code-4.68: hibernate.cfg.xml


                                                                                                                        return to top of the exercise

Summary


In this exercise, you have learned how to map class hierarchy into database tables using 3 different strategies.


                                                                                                                    return to the top




Homework exercise (for people who are taking Sang Shin's "Java EE Programming online course")


1. The homework is to create your own Hibernate projects called HibernateMyMappingTablePerClassHierarchy and  HibernateMyMappingTablePerSubClass as following:

2. Send the following files to j2eehomeworks@sun.com with Subject as J2EEHomework-hibernatemapping.