Sunteți pe pagina 1din 10

About viralpatel.

net Join Us Search Advertise Post Feed


By Viral Patel on December 9, 2011
Home > Hibernate
Hibernate Many To Many XML Mapping Tutorial
Welcome to the Hibernate Tutorial Series. In previous tutorial we saw how to implement One to Many
Annotation mapping as well as XML mapping. In this tutorial we will understand How to implement Bi-
directional Many-to-Many relationship in Hibernate using XML mappings.
Hibernate Tutorial Series
Introduction to Hibernate Framework
Hibernate Maven MySQL Hello World example (XML Mapping)
Hibernate Maven MySQL Hello World example (Annotation)
Understanding Relationship Mapping
One To One Mapping example (XML Mapping)
One To One Mapping example (Annotation)
One To Many Mapping example (XML Mapping)
One To Many Mapping example (Annotation)
Many To Many Mapping example (XML Mapping)
Many To Many Mapping example (Annotation)
Self-Join One To Many Annotations Mapping example
Self-Join Many To Many Annotations Mapping example
Inheritance in Hibernate
One Table Per Class Hierarchy (Annotation & XML mapping)
One Table Per Subclass (Annotation & XML mapping)
One Table Per Concrete Class (Annotation & XML mapping)
First let us see the formal definition of Many-to-Many relationship:
Many-To-Many Relationship:
Alogical data relationship in which the value of one data element can exist in combination
with many values of another data element, and vice versa.
Let us see how to implement Many-to-Many relationship in Hibernate using XML mapping.
1. Create Database
For this example, we will MySQL database. We are using Employee-Meeting relationship as a many to
many relationship example. Each Employee can attain more than one meetings and each meetings can
have more than one employee
.
Latest Posts
Subscribe
Get our Articles via Email. Enter your email.
Your E-Mail

Viral Patel
579 followers
Follow
Home Android Java Spring Frameworks Database JavaScript Web More
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`)
)
ViralPatel.net
4,090 people like ViralPatel.net.
Facebook social plugin
Like Like
Follow on Twitter @viralpatelnet Follow on Twitter @viralpatelnet
converted by Web2PDFConvert.com
2. Hibernate Maven Dependency
We are using Maven for dependency management. Copy following in the pom.xml.
File: pom.xml
Sponsors Links
Taj OS
1. Compound Triggers in Oracle 11g - Tutorial
with example
2. How to pass CLOB argument in EXECUTE
IMMEDIATE
3. How to get Eclipse current workspace path
4. jQuery window height is not correct
5. 45 Useful Oracle Queries
6. JavaScript Singleton Design Pattern
7. AngularJS Service / Factory Tutorial with
Example
8. Oracle XMLTable Tutorial with Example
9. JavaScript 101: Objects and Functions
10. JavaScript Module Design Pattern


CREATE TABLE `meeting` (
`meeting_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`subject` VARCHAR(50) NOT NULL,
`meeting_date` DATE NOT NULL,
PRIMARY KEY (`meeting_id`)
)


CREATE TABLE `employee_meeting` (
`employee_id` BIGINT(20) NOT NULL,
`meeting_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`employee_id`, `meeting_id`),
INDEX `FK_MEETING` (`meeting_id`),
CONSTRAINT `FK_EMPLOYEE` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`),
CONSTRAINT `FK_MEETING` FOREIGN KEY (`meeting_id`) REFERENCES `meeting` (`meeting_id`)
)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
<modelVersion>4.0.0</modelVersion>
<groupId>net.viralpatel.hibernate</groupId>
<artifactId>HibernateHelloWorldXML</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>HibernateHelloWorldXML</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.6.ga</version>
</dependency>
</dependencies>
</project>
converted by Web2PDFConvert.com
3. Hibernate Model Class
Employee and Department model classes are created which maps to the corresponding database tables.
File: Employee.java
File: Meeting.java
4. Hibernate Utility Class
To access Hibernate API, we will create a wrapper utility class which provides us with SessionFactory.
File: HibernateUtil.java
package net.viralpatel.hibernate;

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

public class Employee {

private Long employeeId;
private String firstname;
private String lastname;

private Set<Meeting> meetings = new HashSet<Meeting>();

public Employee() {
}

public Employee(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}

// Getter and Setter methods
}
package net.viralpatel.hibernate;

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

public class Meeting {

private Long meetingId;
private String subject;
private Date meetingDate;

private Set<Employee> employees = new HashSet<Employee>();

public Meeting(String subject) {
this.subject = subject;
this.meetingDate = new Date();
}

// Getter and Setter methods
}
package net.viralpatel.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

private static final SessionFactory sessionFactory = buildSessionFactory();

private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
converted by Web2PDFConvert.com
5. Hibernate Mapping XML (hbm)
Following are the hibernate mapping files for each enitity Employee and Department.
File: Employee.hbm.xml
File: Meeting.hbm.xml
One thing is worth noting here is that we have mentioned keyword inverse=true in Meeting class
which makes Employee as relationship owner. Thus Employee model takes care of updating referential
keys in dependent models.
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
<?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="net.viralpatel.hibernate">

<class name="Employee" table="EMPLOYEE">
<id name="employeeId" column="EMPLOYEE_ID">
<generator class="native" />
</id>

<property name="firstname" />
<property name="lastname" column="lastname" />

<set name="meetings" table="EMPLOYEE_MEETING"
inverse="false" lazy="true" fetch="select" cascade="all">
<key column="EMPLOYEE_ID" />
<many-to-many column="MEETING_ID" class="Meeting" />
</set>

</class>
</hibernate-mapping>
<?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="net.viralpatel.hibernate">

<class name="Meeting" table="MEETING">

<id name="meetingId" type="java.lang.Long"
column="MEETING_ID">
<generator class="native" />
</id>

<property name="subject" column="SUBJECT" />
<property name="meetingDate" type="date" column="MEETING_DATE" />

<set name="employees" table="EMPLOYEE_MEETING"
inverse="true" lazy="true" fetch="select">
<key column="EMPLOYEE_ID" />
<many-to-many column="MEETING_ID" class="Meeting" />
</set>

</class>
</hibernate-mapping>
converted by Web2PDFConvert.com
6. Hibernate Configuration File
Add following hibernate.cfg.xml file in your project.
File: hibernate.cfg.xml
7. Review Project Structure
Note that we have used SET to map meetings with employee and vice versa. A <set> is similar to except
that it can only store unique objects. That means no duplicate elements can be contained in a set. When
you add the same element to a set for second time, it will replace the old one. A set is unordered by
default but we can ask it to be sorted. The corresponding type of a <set> in Java is java.util.Set .
Execute example
File: Main.java
<?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.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/tutorial</property
<property name="connection.username">root</property>
<property name="connection.password"></property>

<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>

<mapping resource="net/viralpatel/hibernate/Employee.hbm.xml"/>
<mapping resource="net/viralpatel/hibernate/Meeting.hbm.xml"/>

</session-factory>
</hibernate-configuration>
package net.viralpatel.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class Main {

public static void main(String[] args) {

SessionFactory sf = HibernateUtil.getSessionFactory();
converted by Web2PDFConvert.com
Output:
Download Source Code
Hibernate-many-to-many-set-xml.zip (9 KB)
Related Articles
1. Hibernate Many To Many Annotation Mapping Tutorial
2. Hibernate One To One Mapping Tutorial (XML Mapping)
3. Hibernate One To One Annotation Mapping Tutorial
4. Hibernate One To Many XML Mapping Tutorial
5. Hibernate Self Join Annotations One To Many mapping example
6. Hibernate Self Join Many To Many Annotations mapping example
7. Hibernate Inheritance: Table Per Class Hierarchy (Annotation & XML Mapping)
Get our Articles via Email. Enter your email address.
Send Me Tutorials
Session session = sf.openSession();
session.beginTransaction();


Meeting meeting1 = new Meeting("Quaterly Sales meeting");
Meeting meeting2 = new Meeting("Weekly Status meeting");

Employee employee1 = new Employee("Sergey", "Brin");
Employee employee2 = new Employee("Larry", "Page");

employee1.getMeetings().add(meeting1);
employee1.getMeetings().add(meeting2);
employee2.getMeetings().add(meeting1);

session.save(employee1);
session.save(employee2);

session.getTransaction().commit();
session.close();
}
}
Hibernate: insert into EMPLOYEE (firstname, lastname) values (?, ?)
Hibernate: insert into MEETING (SUBJECT, MEETING_DATE) values (?, ?)
Hibernate: insert into MEETING (SUBJECT, MEETING_DATE) values (?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname) values (?, ?)
Hibernate: insert into EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)
Hibernate: insert into EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)
Hibernate: insert into EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)
converted by Web2PDFConvert.com
17 February, 2012, 21:53
9 March, 2012, 17:30
9 March, 2012, 17:59
15 March, 2012, 12:19
29 March, 2012, 17:40
5 April, 2012, 23:30
5 April, 2012, 23:37

Tags: HIBERNATE, MAVEN, MYSQL
18 Comments
Tomasz
Hi there! I mapped my tables based on above. They works I can load or save. But I cant delete.
When i tried to say something like this:
Employee e = (Employee) session.load(Employee.class,1);
session.delete(e);
I get the SEVERE: Cannot delete or update a parent row: a foreign key constraint fails error.
I tried to implements PreDeleteEventListener and delete the child(Employee_Metting) before delete
a Employee row, but another exception is throwed the Employee_Metting is not mapped. Must I
map this table? Or could I do this without it?
Reply
sravankumar
Hi, i got this error, while executing the above example, can you please help me.
here my doubt is : whether we have to create table EMPLOYEE_MEETING or hibernate will create
it. i want clarity in it. thanks for ur reply
Reply
Viral Patel
Hi,
In this case, table Employee_Meeting is not created by Hibernate. You have to explicitly do
this in your database. This is because in our hibernate.cfg.xml file, we have define value for
key hibernate.hbm2ddl.auto to validate. Change it to create-drop or create to let Hibernate
create schema for you. Read this article for more details.
Hope this helps.
Reply
Rajesh
Nice article Viral
Keep on posting in simplified manner. It really help the beginers to understand actual
scenarions Thanks
Reply
suresh
Hi,
after running this example the employee-meeting containg only three rows of values.but it should
contain the four rows of values.why because the employee and meeting tables conatins 2 rows of
values in each table.can you clarify
Reply
tecfinder
Hi Suresh,
Please see the main() method. Employee1 is associated with two meeting object and
Employee2 is associated with one meeting object so total number of associations is 3.
This is the reason why we have 3 records in Employee_Meeting table
Reply
tecfinder
75 [main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml

org.hibernate.HibernateException: Missing table: EMPLOYEE_MEETING
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:

Caused by: org.hibernate.HibernateException: Missing table: EMPLOYEE_MEETING
converted by Web2PDFConvert.com
19 October, 2012, 10:39
16 December, 2012, 18:19
22 December, 2012, 9:38
5 January, 2013, 2:08
Hi Viral,
Cascade=all is meaningless in the above case as in many to many association we can have
multiple parents and an instance of object cant be deleted if one parent is deleted.It should be
save-update
Reply
Mayur Mistry
Nice article. Simple to understand.
Reply
Ingo
How to make the Meeting class as owner in this case?
Reply
Kevin
Hi,
I think your mapping in the Meeting.hbm.xml is wrong. It should be:
Reply
david
Thanks for the good tutorial. After having executed the example, I manually inserted another record
into the employee table, and than updated the code in the main method with the following code (I
was trying to read the many to many relationship records).
List empList = session.createQuery(from Employee).list();
if (empList!=null && empList.size()>0) {
for (Employee employee: empList) {
System.out.println(\n employee.getLastname(): + employee.getLastname());
Set empMeetings = employee.getMeetings();
if (empMeetings!=null) {
if (empMeetings.size()==0) {
System.out.println(meeting subject for + employee.getLastname() + is 0);
} else {
Iterator mIterator = empMeetings.iterator();
while (mIterator.hasNext()) {
Meeting m = mIterator.next();
System.out.println(meeting subject for + employee.getLastname() + : + m.getSubject());
}
}
} else {
System.out.println(meeting subject for + employee.getLastname() + is null);
}
}
}
The output was as the following. From the output, we can find out that 4 queries were executed to
get all employees with the meetings.
emp.getLastname(): Brin
Hibernate: select meetings0_.EMPLOYEE_ID as EMPLOYEE1_1_, meetings0_.MEETING_ID as
MEETING2_1_, meeting1_.MEETING_ID as MEETING1_2_0_, meeting1_.SUBJECT as
SUBJECT2_0_, meeting1_.MEETING_DATE as MEETING3_2_0_ from EMPLOYEE_MEETING
meetings0_ left outer join MEETING meeting1_ on
meetings0_.MEETING_ID=meeting1_.MEETING_ID where meetings0_.EMPLOYEE_ID=?
meeting subject for Brin: Weekly Status meeting
meeting subject for Brin: Quaterly Sales meeting
emp.getLastname(): Page
Hibernate: select meetings0_.EMPLOYEE_ID as EMPLOYEE1_1_, meetings0_.MEETING_ID as
MEETING2_1_, meeting1_.MEETING_ID as MEETING1_2_0_, meeting1_.SUBJECT as
SUBJECT2_0_, meeting1_.MEETING_DATE as MEETING3_2_0_ from EMPLOYEE_MEETING
meetings0_ left outer join MEETING meeting1_ on
meetings0_.MEETING_ID=meeting1_.MEETING_ID where meetings0_.EMPLOYEE_ID=?
meeting subject for Page: Quaterly Sales meeting
emp.getLastname(): last_name1
Hibernate: select meetings0_.EMPLOYEE_ID as EMPLOYEE1_1_, meetings0_.MEETING_ID as
MEETING2_1_, meeting1_.MEETING_ID as MEETING1_2_0_, meeting1_.SUBJECT as
SUBJECT2_0_, meeting1_.MEETING_DATE as MEETING3_2_0_ from EMPLOYEE_MEETING
meetings0_ left outer join MEETING meeting1_ on
meetings0_.MEETING_ID=meeting1_.MEETING_ID where meetings0_.EMPLOYEE_ID=?
converted by Web2PDFConvert.com
23 March, 2013, 20:12
19 May, 2013, 18:04
24 May, 2013, 12:36
24 May, 2013, 12:58
11 December, 2013, 2:59
2 June, 2013, 18:16
meeting subject for last_name1 is 0
Is it possible to get all employees with the meetings by executing a single query? If so, can you
point out the direction about how to do it?
Thank you!
Reply
Just soneone
http://stackoverflow.com/questions/15560856/nhibernate-bidirectional-many-to-many-mapping-list-
bag
But I would like to give you a hint. Try to change the approach and introduce the intermediate object.
See the NHibernate documentation: Chapter 24. Best Practices. Quick summary:
Dont use exotic association mappings.
Good usecases for a real many-to-many associations are rare. Most of the time you need
additional information stored in the link table. In this case, it is much better to use two one-to-
many associations to an intermediate link class. In fact, we think that most associations are one-
to-many and many-to-one, you should be careful when using any other association style and ask
yourself if it is really neccessary.
And I would say, that this is (could be) the case, because you really need the Order
Reply
Swaroop
Hi
When I created the same scenario in my project, I got the following exception when Im trying to
delete a record from one of the base tables involved in the Many-to-Many mapping.
Exception:
Caused by: net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier
value was already associated with the session
Please suggest what am I supposed to do.
Thanks
Reply
pushpendra
Cannot add or update a child row: a foreign key constraint fails (`test`.`employee_meeting`,
CONSTRAINT `FK_EMPLOYEE` FOREIGN KEY (`employee_id`) REFERENCES `employee`
(`employee_id`))
Reply
pushpendra
error spotted in your meeting.hbm.xml
please check key column and and many to many column
still despite all the fact that still getting same error
Cannot add or update a child row: a foreign key constraint fails (`test`.`employee_meeting`,
CONSTRAINT `FK_EMPLOYEE` FOREIGN KEY (`employee_id`) REFERENCES `employee`
(`employee_id`))
Reply
tecfinder
Pushpendra,
One more correction, class attribute should contain Employee value instead of Meeting
in many to many tag
Reply
shailesh
Is there any way to update Just employee information? If I have two different UIs, one for Employee
and one for associating Employee to meetings, then if I just want to save employee information
<set name="employees" table="EMPLOYEE_MEETING"
inverse="true" lazy="true" fetch="select">
<key column="EMPLOYEE_ID" />
<many-to-many column="MEETING_ID" class="Meeting" />
</set>
converted by Web2PDFConvert.com
18 September, 2013, 12:59
(with meetings null) then it deletes all the meetings for that employee. Is there any way to avoid this
delete? Im using cascade=save-update
Reply
venkatadri
Hi patel,
it is very really good article for hibernate beginners, thanx a lot.
Reply
Leave a Reply
Your email address will not be published. Required fields are marked *
Name *
Email *
Website
Comment
Note
To post source code in comment, use [code language] [/code] tag, for example:
[code java] Java source code here [/code]
[code html] HTML here [/code]
Post Comment
Home page Struts Spring AJAX PHP Java JavaEE
JavaScript CSS Database Web 2.0 News Fun
General Featured Play Framework Android
FreeMarker Template
Categories
About viralpatel.net Join Us Search Advertise
Posts Feed Comments Feed
Site Pages Back to top
Copyright 2014 ViralPatel.net. All rights reserved :)
converted by Web2PDFConvert.com

S-ar putea să vă placă și