Figure 11.1 illustrates Self Reference one-to-many relationship.
Figure 11.1
According to this relationship each person can have friends and each friend is a person.
First create a new Java Project and configure it as Maven Project. For Reference, Click Here
Add the following dependencies in pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.15</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.3.Final</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
</dependencies>
1. Sql Script
Use the following Sql Script for creating table.
create table Person(
person_id int(10) primary key NOT NULL AUTO_INCREMENT,
Name varchar(50));
create table friends(
person_id int(10) NOT NULL REFERENCES person (person_id),
friend_id int(10) NOT NULL REFERENCES person (person_id),
PRIMARY KEY (person_id, friend_id)
);
2. Pojo
Now create Person Class as following.
Person.java
package com.kruders.model.bean;
import java.util.HashSet;
import java.util.Set;
public class Person {
private int personId;
private String name;
private Set<Person> persons = new HashSet<Person>();
private Set<Person> friends = new HashSet<Person>();
public Person() {
}
public Person(String name) {
this.name = name;
}
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Person> getPersons() {
return persons;
}
public void setPersons(Set<Person> persons) {
this.persons = persons;
}
public Set<Person> getFriends() {
return friends;
}
public void setFriends(Set<Person> friends) {
this.friends = friends;
}
}
We have defined two attributes Set<Person> persons and Set<Person> friends. These attributes are mapped with many-to-many as shown in hibernate mapping file.
3. Hibernate Mapping File
Now create HBM file Person.hbm.xml that maps classes to database tables.
<?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>
<class name="com.kruders.model.bean.Person" table="PERSON">
<meta attribute="class-description">This class contains person details.</meta>
<id name="personId" type="int" column="person_id">
<generator class="native" />
</id>
<property name="name" type="string" length="50" column="NAME" />
<set name="persons" table="friends" cascade="none" lazy="false">
<key column="person_id"/>
<many-to-many column="friend_id" class="com.kruders.model.bean.Person" />
</set>
<set name="friends" table="friends" cascade="none" lazy="false">
<key column="friend_id"/>
<many-to-many column="person_id" class="com.kruders.model.bean.Person" />
</set>
</class>
</hibernate-mapping>
4. Hibernate Configuration File
Now create the hibernate configuration file and add all the mapping files.
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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="connection.pool_size">1</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <mapping resource="com/kruders/model/bean/Person.hbm.xml"/> </session-factory> </hibernate-configuration>
5. Hibernate Utility Class
Now create HibernateUtil class. The HibernateUtil class helps in creating the SessionFactory from the Hibernate configuration file. A org.hibernate.SessionFactory is used to obtain org.hibernate.Session instances. A org.hibernate.Session represents a single-threaded unit of work. The org.hibernate.SessionFactory is a thread-safe global object that is instantiated once.
package com.kruders.util;
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();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
6. Run Program
Create Main.java> class that perform CRUD operations and run it as Java Application
package com.kruders.core;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.kruders.model.bean.Person;
import com.kruders.util.HibernateUtil;
public class Main {
public static void main(String args[]) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Person person1 = new Person("Puneet");
Person person2 = new Person("Rahul");
Person person3 = new Person("Shally");
Set friends=new HashSet();
friends.add(person2);
friends.add(person3);
person1.setFriends(friends);
session.save(person2);
session.save(person3);
session.save(person1);
transaction.commit();
}catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
//listEmployee();
//updateEmployee("Puneet", "Raghav");
//listEmployee();
//deleteEmployee(3);
}
public void listEmployee() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
List persons = session.createQuery("from Person").list();
for (Iterator iterator = persons.iterator(); iterator.hasNext();) {
Person person = (Person) iterator.next();
System.out.println("Name " + person.getName());
}
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public void updateEmployee(String oldName, String newName) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
List persons = session.createQuery("from Person where Name ='" + oldName + "'").list();
for (Iterator iterator = persons.iterator(); iterator.hasNext();) {
Person person = (Person) iterator.next();
person.setName(newName);
}
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public void deleteEmployee(Integer employeeId) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
List<Person> persons = session.createQuery("from Person where personId ='" + employeeId + "'").list();
for(Person person : persons) {
System.out.println("Name " + person.getName());
session.delete(person);
}
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
The folder structure of the example is shown below in Figure 11.2
Figure 11.2

This is really a good tutorial, will you please help more in depth about what will be the mapping if i want to add extra columns to friends table like date of friendship start. event or place.
instead of using Person Class in Set mapping can how to use a friend class
Regards
@Ahsan
You can refer this link..
http://kruders.com/hibernate/hibernate-self-join-many-to-many-mapping-with-extra-column-using-annotation/