In this post under Hibernate, I will explain how to create a unidirectional one to many association between objects using a mapping file with an example.
For our example, we will create the below two tables.
Data Definition Language
CREATE TABLE `series1` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;
CREATE TABLE `season1` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(100) NOT NULL,
`series_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `FK_season_series` (`series_id`),
CONSTRAINT `FK_season_series` FOREIGN KEY (`series_id`) REFERENCES `series1` (`id`) ON UPDATE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;
According to above sql code, I have created two tables “series1” and “season1”. In Object Oriented world, there will be one to many association between “series1” and “season1”. In other words one “series1” instance will have multiple instances of “season1”. So to create a one to many association in RDBMS, I have added a foreign key “series_id” column in “season1” table. This foreign key will refer to primary column in “series1” table.
Next we will create java classes for the above tables
Series1 Class
import java.util.Set;
public class Series1 {
private int id;
private String name;
private String description;
private Set seasons;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set getSeasons() {
return seasons;
}
public void setSeasons(Set seasons) {
this.seasons = seasons;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(id).append(":");
sb.append(name).append(":");
sb.append(description);
return sb.toString();
}
}
Season1 Class
public class Season1 {
private int id;
private String name;
private String description;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(id).append(":");
sb.append(name).append(":");
sb.append(description);
return sb.toString();
}
}
Since we are creating an unidirectional one to many association meaning the navigation will be from one side to many side. In the Series1 class code, we have added “seasons” property of type Set containing “Season1” class instances. Series1 class is on one side and Season1 class is on many side.
Next we add hbm.xml file for the above java classes
Season1.hbm.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5 <hibernate-mapping>
6 <class name="Season1" table="Season1">
7 <id type="int" name="id" column="id">
8 <generator class="native"/>
9 </id>
10 <property name="name" column="name" type="string"/>
11 <property name="description" column="description" type="string"/>
12 </class>
13 </hibernate-mapping>
Series1.hbm.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5 <hibernate-mapping>
6 <class name="Series1" table="Series1">
7 <id type="int" name="id" column="id">
8 <generator class="native"/>
9 </id>
10 <property name="name" column="name" type="string"/>
11 <property name="description" column="description" type="string"/>
12 <set name="seasons" cascade="all">
13 <key column="series_id"/>
14 <one-to-many class="Season1"/>
15 </set>
16 </class>
17 </hibernate-mapping>
In the above xml file, to create a unidirectional one to many mapping we add the xml code starting from line 12 to 15 as shown below
12 <set name="seasons" cascade="all">
13 <key column="series_id"/>
14 <one-to-many class="Season1"/>
15 </set>
Since we are creating unidirectional one to many association (i.e., navigation is from Series1 to Season1) we will add the above xml snippet in Series.hbm.xml file.
1) The set element’s name attribute’s value matches with the property name “seasons” in Series1.java file.
2) The column attribute’s value in key element, matches with the foreign key column name “series_id” added in “season1” table.
3) The one-to-many element’s class attribute’s value will have the class name of the class at the many side of the relationship. In this case it will be “Season1”.
Below is hibernate configuration file for your reference
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/examples</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- <property name="hibernate.hbm2ddl.auto">create</property> -->
<property name="hibernate.show_sql">true</property>
<mapping resource="Series1.hbm.xml"/>
<mapping resource="Season1.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Below is the main code
Main Code
1 import java.util.HashSet;
2 import java.util.Set;
3
4 import org.hibernate.Session;
5 import org.hibernate.SessionFactory;
6
7 public class HibernateDemo10 {
8 public static void main(String[] args) {
9 SessionFactory sessionFactory = HibernateUtil.createSessionFactory();
10
11 Series1 series = new Series1();
12 series.setName("Monk");
13 series.setDescription("Monk");
14
15 Season1 season1 = new Season1();
16 season1.setName("Season1");
17 season1.setDescription("Season1");
18
19 Season1 season2 = new Season1();
20 season2.setName("Season2");
21 season2.setDescription("Season2");
22
23 Set set = new HashSet();
24 set.add(season1);
25 set.add(season2);
26
27 series.setSeasons(set);
28
29 Session session = sessionFactory.openSession();
30 session.beginTransaction();
31 int id = (Integer)session.save(series);
32 session.getTransaction().commit();
33 session.close();
34
35 series = null;
36
37 session = sessionFactory.openSession();
38 series = session.load(Series1.class, id);
39 System.out.println(series);
40 for(Season1 season : series.getSeasons()) {
41 System.out.println(season);
42 }
43 session.close();
44 HibernateUtil.shutdown();
45 }
46 }
In the above main code, at line 11 I create an instance of Series1. At line 15, 19 I create two instances of Season1 and add them to set at line 23.
At line 27, I set the collection to series instance.
At line 31, I save the object series. The informmation in series object, two Season1 object and the association between Series1 and Season1 instances are also saved.