Hibernate Framework : ORM Tool :: Hibernate Association Mapping Examples
- Association Mapping Intro
- Difference between bi-directional and Uni-directional
- One-to-One Mapping Example
- Many-to-One Mapping Example OR One-to-Many Mapping Example
- Many-to-Many Mapping Example
- Download Examples
Association Mapping Intro |
- Association mappings are often the most difficult thing to implement correctly.
- In this section we examine some canonical cases one by one, starting with unidirectional mappings and then bidirectional cases.
- We will use Person and Address in all the examples.
- Associations will be classified by multiplicity and whether or not they map to an intervening join table.
- Nullable foreign keys are not considered to be good practice in traditional data modelling, so our examples do not use nullable foreign keys.
This is not a requirement of Hibernate, and the mappings will work if you drop the nullability constraints.
- 1. Many-to-One
- 2. One-to-One
- 3. Many-to-Many
Syntax
1. Many-to-one
A unidirectional many-to-one association is the most common kind of unidirectional association.
<class name="Person">
<id name="id" column="personId">
< generator class="native"/>
</id>
< many-to-one name="address" column="addressId" not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
< generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
2. One-to-one
A unidirectional one-to-one association on a foreign key is almost identical. The only difference is the column unique constraint.
<class name="Person">
<id name="id" column="personId">
< generator class="native"/>
</id>
< many-to-one name="address" column="addressId" unique="true" not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
< generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
A unidirectional one-to-one association on a primary key usually uses a special id generator In this example, however, we have reversed the direction of the association:
<class name="Person">
<id name="id" column="personId">
< generator class="native"/>
</id>
</class>
<class name="Address">
<id name="id" column="personId">
< generator class="foreign">
<param name="property">person</param>
< /generator>
</id>
< one-to-one name="person" constrained="true"/>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
3. One-to-many
A unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended.
<class name="Person">
<id name="id" column="personId">
< generator class="native"/>
</id>
<set name="addresses">
<key column="personId" not-null="true"/>
< one-to-many class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
< generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key, personId bigint not null )
Difference between unidirectional and bidirectional |
Since the table generated in the db are all the same, so the only difference I found is that each side of the bidiretional assocations will have a refer to the other,and the unidirectional not.
This is a Unidirectional association
public class User {
private int id;
private String name;
@ManyToOne
@JoinColumn(
name = "groupId")
private Group group;
}
public class Group {
private int id;
private String name;
}
The Bidirectional association
public class User {
private int id;
private String name;
@ManyToOne
@JoinColumn(
name = "groupId")
private Group group;
}
public class Group {
private int id;
private String name;
@OneToMany(mappedBy="group")
private List<User> users;
}
One-to-one Mapping |
Hibernate Association One-to-One Mapping Project Hierarchy
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>
<property name="connection.username">root</property>
<property name="connection.url">jdbc:mysql://localhost:3306/javaskoolDB</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="myeclipse.connection.profile">javaskoolMySQLDriver</property>
<property name="connection.password">admin</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping resource="com/javaskool/address.hbm.xml" />
<mapping resource="com/javaskool/person.hbm.xml" />
</session-factory>
</hibernate-configuration>
Person.java
package com.javaskool;
public class Person {
private Integer id;
private String name;
private Integer age;
Address address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Address.java
package com.javaskool;
public class Address {
private Integer addid;
private String streetName;
private String houseNo;
Person person;
public Integer getAddid() {
return addid;
}
public void setAddid(Integer addid) {
this.addid = addid;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getHouseNo() {
return houseNo;
}
public void setHouseNo(String houseNo) {
this.houseNo = houseNo;
}
}
person.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javaskool">
<class name="Person" table="personsTab">
<id name="id">
<generator class="assigned"></generator>
</id>
<property name="name"></property>
<property name="age"></property>
<one-to-one name="address" class="Address" lazy="false"></one-to-one>
<!--
lazy (optional - defaults to proxy): by default, single point associations
are proxied. lazy="no-proxy" specifies that the property should be fetched
lazily when the instance variable is first accessed.
It requires build-time bytecode instrumentation. lazy="false" specifies
that the association will always be eagerly fetched.
Note that if constrained="false", proxying is impossible and
Hibernate will eagerly fetch the association.
-->
</class>
</hibernate-mapping>
address.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javaskool">
<class name="Address" table="addressTab">
<id name="addid">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="streetName"></property>
<property name="houseNo"></property>
<one-to-one name="person" class="Person" constrained="true"/>
<!--
constrained (optional): specifies that a foreign key constraint
on the primary key of the mapped table and references the table
of the associated class. This option affects the order in which
save() and delete() are cascaded, and determines whether
the association can be proxied. It is also used by the
schema export tool.
-->
</class>
</hibernate-mapping>
TestDrive.java
package com.javaskool;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestDrive {
public static void main(String[] args) {
Person p=new Person();
Address add=new Address();
p.setId(101);
p.setName("James Bond");
p.setAge(35);
p.setAddress(add);
add.setAddid(101);
add.setHouseNo("F6");
add.setStreetName("X Meridian Layout");
add.setPerson(p);
Configuration config=new Configuration().configure();
SessionFactory sf=config.buildSessionFactory();
Session sess=sf.openSession();
Transaction tran=sess.beginTransaction();
sess.save(p);
sess.save(add);
tran.commit();
}
}
Hibernate Genereated Table.
mysql> show create table personsTab;
| CREATE TABLE `personstab` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> show create table addressTab;
| CREATE TABLE `addresstab` (
`addid` int(11) NOT NULL,
`streetName` varchar(255) DEFAULT NULL,
`houseNo` varchar(255) DEFAULT NULL,
PRIMARY KEY (`addid`),
KEY `FK4FEEB701AD9726DA` (`addid`),
CONSTRAINT `FK4FEEB701AD9726DA` FOREIGN KEY (`addid`) REFERENCES `personstab`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
Hibernate Genereated Query
Hibernate: insert into personsTab (name, age, id) values (?, ?, ?)
Hibernate: insert into addressTab (streetName, houseNo, addid) values (?, ?, ?)
mysql> select * from personsTab;
+-----+------------+------+
| id | name | age |
+-----+------------+------+
| 101 | James Bond | 35 |
+-----+------------+------+
1 row in set (0.00 sec)
mysql> select * from addressTab;
+-------+-------------------+---------+
| addid | streetName | houseNo |
+-------+-------------------+---------+
| 101 | X Meridian Layout | F6 |
+-------+-------------------+---------+
1 row in set (0.00 sec)
If You run TestDrive Again , Following Message will come.Duplicate entry ‘101’ for key ‘PRIMARY’
Many-to-one Mapping |
Hibernate Association Many-to-One Mapping Project Hierarchy
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>
<property name="connection.username">root</property>
<property name="connection.url">jdbc:mysql://localhost:3306/javaskoolDB</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="myeclipse.connection.profile">javaskoolMySQLDriver</property>
<property name="connection.password">admin</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping resource="com/javaskool/employee.hbm.xml" />
<mapping resource="com/javaskool/project.hbm.xml" />
</session-factory>
</hibernate-configuration>
Employee.java
package com.javaskool;
import java.util.HashSet;
import java.util.Set;
public class Employee {
private String empId;
private String firstName;
private String lastName;
private Set<Project> projects=new HashSet<Project>();
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public Set<Project> getProjects() {
return projects;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
public void addProject(Project prj)
{
projects.add(prj);
}
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;
}
}
Project.java
package com.javaskool;
public class Project {
private String id;
private String title;
private String customer;
private Employee employee;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
}
employee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javaskool">
<class name="Employee" table="employeeTab" lazy="false">
<id name="empId" column="emp_id"/>
<property name="firstName"></property>
<property name="lastName"></property>
<set name="projects" lazy="true">
<key column="emp_id"></key>
<one-to-many class="Project"/>
</set>
</class>
</hibernate-mapping>
project.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javaskool">
<class name="Project" table="projectTab">
<id name="id"/>
<property name="title"></property>
<property name="customer"></property>
<many-to-one name="employee" class="Employee" column="emp_id"/>
</class>
</hibernate-mapping>
TestDrive.java
package com.javaskool;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestDrive {
public static void main(String[] args) {
Employee e1=new Employee();
Project proj1=new Project();
proj1.setId("P0011"); proj1.setTitle("Trading System");
proj1.setCustomer("Zing Associates"); proj1.setEmployee(e1);
Project proj2=new Project();
proj2.setId("P0022"); proj2.setTitle("Payroll System");
proj2.setCustomer("Zigma Tech Ltd"); proj2.setEmployee(e1);
e1.setEmpId("E0001");
e1.setFirstName("Jennifer"); e1.setLastName("Luies");
e1.addProject(proj1); e1.addProject(proj2);
Configuration config=new Configuration().configure();
SessionFactory sf=config.buildSessionFactory();
Session sess=sf.openSession();
Transaction tran=sess.beginTransaction();
sess.save(e1); sess.save(proj1); sess.save(proj2);
tran.commit();
}
}
Hibernate Genereated Query.
Hibernate: insert into employeeTab (firstName, lastName, emp_id) values (?, ?, ?)
Hibernate: insert into projectTab (title, customer, emp_id, id) values (?, ?, ?, ?)
Hibernate: insert into projectTab (title, customer, emp_id, id) values (?, ?, ?, ?)
Hibernate: update projectTab set emp_id=? where id=?
Hibernate: update projectTab set emp_id=? where id=?
Hibernate Genereated Table.
mysql> show create table employeeTab;
| employeeTab | CREATE TABLE `employeetab` (
`emp_id` varchar(255) NOT NULL,
`firstName` varchar(255) DEFAULT NULL,
`lastName` varchar(255) DEFAULT NULL,
PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> show create table projecttab;
| projectTab | CREATE TABLE `projecttab` (
`id` varchar(255) NOT NULL,
`title` varchar(255) DEFAULT NULL,
`customer` varchar(255) DEFAULT NULL,
`emp_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK8A9479BCC81C0669` (`emp_id`),
CONSTRAINT `FK8A9479BCC81C0669` FOREIGN KEY (`emp_id`) REFERENCES `employeetab` (`emp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> select * from employeeTab;
+--------+-----------+----------+
| emp_id | firstName | lastName |
+--------+-----------+----------+
| E0001 | Jennifer | Luies |
+--------+-----------+----------+
1 row in set (0.00 sec)
mysql> select * from projectTab;
+-------+----------------+-----------------+--------+
| id | title | customer | emp_id |
+-------+----------------+-----------------+--------+
| P0011 | Trading System | Zing Associates | E0001 |
| P0022 | Payroll System | Zigma Tech Ltd | E0001 |
+-------+----------------+-----------------+--------+
2 rows in set (0.00 sec)
Many-to-Many Mapping |
Hibernate Association Many-to-Many Mapping Project Hierarchy
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>
<property name="connection.username">root</property>
<property name="connection.url">jdbc:mysql://localhost:3306/javaskoolDB</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="myeclipse.connection.profile">javaskoolMySQLDriver</property>
<property name="connection.password">admin</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping resource="com/javaskool/student.hbm.xml" />
<mapping resource="com/javaskool/batch.hbm.xml" />
</session-factory>
</hibernate-configuration>
Student.java
package com.javaskool;
import java.util.HashSet;
import java.util.Set;
public class Student {
private String id;
private String firstName;
private Integer age;
private Set<Batch> batches=new HashSet<Batch>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Set<Batch> getBatches() {
return batches;
}
public void setBatches(Set<Batch> batches) {
this.batches = batches;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Batch.java
package com.javaskool;
import java.util.HashSet;
import java.util.Set;
public class Batch {
private String id;
private String title;
private String fee;
private Set<Student> students=new HashSet<Student>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public void addStudent(Student s)
{
students.add(s);
s.getBatches().add(this);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFee() {
return fee;
}
public void setFee(String fee) {
this.fee = fee;
}
}
student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javaskool">
<class name="Student" table="students">
<id name="id" column="student_id"/>
<property name="firstName"></property>
<property name="age"></property>
<set name="batches" table="bat_stu_details" inverse="true">
<key column="student_id"/>
<many-to-many class="Batch" column="batch_id"/>
</set>
</class>
</hibernate-mapping>
batch.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javaskool">
<class name="Batch" table="batch">
<id name="id" column="batch_id"/>
<property name="title"></property>
<property name="fee"></property>
<set name="students" table="bat_stu_details">
<key column="batch_id"/>
<many-to-many class="Student" column="student_id"/>
</set>
</class>
</hibernate-mapping>
TestDrive.java
package com.javaskool;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestDrive {
public static void main(String[] args) {
Batch b1=new Batch();
b1.setId("B0001"); b1.setTitle("Java/J2EE"); b1.setFee("15000");
Batch b2=new Batch();
b2.setId("B0002"); b2.setTitle("Oracle11g"); b2.setFee("10000");
Student s1=new Student();
Student s2=new Student();
s1.setId("S0001"); s1.setFirstName("John"); s1.setAge(31);
s2.setId("S0002"); s2.setFirstName("James"); s2.setAge(32);
b1.addStudent(s1); b1.addStudent(s2);
b2.addStudent(s1); b2.addStudent(s2);
Configuration config=new Configuration().configure();
SessionFactory sf=config.buildSessionFactory();
Session sess=sf.openSession();
Transaction tran=sess.beginTransaction();
sess.save(b1); sess.save(b2);
sess.save(s1); sess.save(s2);
tran.commit();
}
}
Hibernate Genereated Query.
Hibernate: insert into batch (title, fee, batch_id) values (?, ?, ?)
Hibernate: insert into batch (title, fee, batch_id) values (?, ?, ?)
Hibernate: insert into students (firstName, age, student_id) values (?, ?, ?)
Hibernate: insert into students (firstName, age, student_id) values (?, ?, ?)
Hibernate: insert into bat_stu_details (batch_id, student_id) values (?, ?)
Hibernate: insert into bat_stu_details (batch_id, student_id) values (?, ?)
Hibernate: insert into bat_stu_details (batch_id, student_id) values (?, ?)
Hibernate: insert into bat_stu_details (batch_id, student_id) values (?, ?)
Hibernate Genereated Table.
mysql> show create table batch;
| batch | CREATE TABLE `batch` (
`batch_id` varchar(255) NOT NULL,
`title` varchar(255) DEFAULT NULL,
`fee` varchar(255) DEFAULT NULL,
PRIMARY KEY (`batch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> show create table student;
| students | CREATE TABLE `students` (
`student_id` varchar(255) NOT NULL,
`firstName` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> show create table bat_stu_details;
| bat_stu_details | CREATE TABLE `bat_stu_details` (
`batch_id` varchar(255) NOT NULL,
`student_id` varchar(255) NOT NULL,
PRIMARY KEY (`batch_id`,`student_id`),
KEY `FK2A06460DD4FC9AF1` (`student_id`),
KEY `FK2A06460DD978E051` (`batch_id`),
CONSTRAINT `FK2A06460DD978E051` FOREIGN KEY (`batch_id`) REFERENCES `batch` (`batch_id`),
CONSTRAINT `FK2A06460DD4FC9AF1` FOREIGN KEY (`student_id`) REFERENCES `students` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> select * from batch;
+----------+-----------+-------+
| batch_id | title | fee |
+----------+-----------+-------+
| B0001 | Java/J2EE | 15000 |
| B0002 | Oracle11g | 10000 |
+----------+-----------+-------+
2 rows in set (0.00 sec)
mysql> select * from students;
+------------+-----------+------+
| student_id | firstName | age |
+------------+-----------+------+
| S0001 | John | 31 |
| S0002 | James | 32 |
+------------+-----------+------+
2 rows in set (0.00 sec)
mysql> select * from bat_stu_details;
+----------+------------+
| batch_id | student_id |
+----------+------------+
| B0001 | S0001 |
| B0002 | S0001 |
| B0001 | S0002 |
| B0002 | S0002 |
+----------+------------+
4 rows in set (0.02 sec)
Download Examples |
Recent Comments