
A many-to-many association
We are going to develop a sample Hibernate application that manages the above association in which a user may belong to many groups, and a group may contain many users. The UsersGroups is the join table between the groups and users tables.The following pieces of software/library are used in this tutorial:create database usersdb; use usersdb; CREATE TABLE `users` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(45) NOT NULL, `password` varchar(45) NOT NULL, `email` varchar(45) NOT NULL, PRIMARY KEY (`user_id`) ); CREATE TABLE `groups` ( `group_id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) NOT NULL, PRIMARY KEY (`group_id`) ); CREATE TABLE `UsersGroups` ( `user_id` int(11) NOT NULL, `group_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`group_id`), KEY `fk_user` (`user_id`), KEY `fk_group` (`group_id`), CONSTRAINT `fk_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`), CONSTRAINT `fk_group` FOREIGN KEY (`group_id`) REFERENCES `groups` (`group_id`) );Or type the following command in case you are using MySQL Command Line Client program:
source Path\To\The\Script\File\MySQLscript.sql
In which the MySQLscript.sql file can be created from the above script or picked up from the attached project. The newly created database would have the following structure:
As we can see, the project contains the following files:package net.codejava.hibernate;
import java.util.HashSet;
import java.util.Set;
public class Group {
private long id;
private String name;
private Set<User> users = new HashSet<User>();
public Group(String name) {
this.name = name;
}
public void addUser(User user) {
this.users.add(user);
}
// setters and getters
} File net\codejava\hibernate\User.java:package net.codejava.hibernate;
import java.util.HashSet;
import java.util.Set;
public class User {
private long id;
private String username;
private String password;
private String email;
private Set<Group> groups = new HashSet<Group>();
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
public void addGroup(Group group) {
this.groups.add(group);
}
// setters and getters
}NOTES: For a bidirectional many-to-many association, we should specify a collection of another side from each side (using java.util.Set implementation in this tutorial). For example:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.codejava.hibernate">
<class name="Group" table="GROUPS">
<id name="id" column="GROUP_ID">
<generator class="native"/>
</id>
<property name="name" column="NAME" />
<set name="users" table="UsersGroups" cascade="save-update">
<key column="GROUP_ID"/>
<many-to-many column="USER_ID" class="User" />
</set>
</class>
</hibernate-mapping> File net\codejava\hibernate\User.hbm.xml:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.codejava.hibernate">
<class name="User" table="USERS">
<id name="id" column="USER_ID">
<generator class="native"/>
</id>
<property name="username" column="USERNAME" />
<property name="password" column="PASSWORD" />
<property name="email" column="EMAIL" />
<set name="groups" table="UsersGroups" inverse="true">
<key column="USER_ID"/>
<many-to-many column="GROUP_ID" class="Group" />
</set>
</class>
</hibernate-mapping> NOTES:<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/usersdb</property>
<property name="connection.username">root</property>
<property name="connection.password">secret</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping resource="net/codejava/hibernate/User.hbm.xml"/>
<mapping resource="net/codejava/hibernate/Group.hbm.xml"/>
</session-factory>
</hibernate-configuration>NOTES: Change the username and password according to your MySQL account. package net.codejava.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
/**
* A program that demonstrates using Hibernate framework to manage
* a bidirectional many-to-many association in relational database.
* @author www.codejava.net
*
*/
public class UsersManager {
public static void main(String[] args) {
// loads configuration and mappings
Configuration configuration = new Configuration().configure();
ServiceRegistryBuilder registry = new ServiceRegistryBuilder();
registry.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = registry.buildServiceRegistry();
// builds a session factory from the service registry
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistry);
// obtains the session
Session session = sessionFactory.openSession();
session.beginTransaction();
Group groupAdmin = new Group("Administrator Group");
Group groupGuest = new Group("Guest Group");
User user1 = new User("Tom", "tomcat", "tom@codejava.net");
User user2 = new User("Mary", "mary", "mary@codejava.net");
groupAdmin.addUser(user1);
groupAdmin.addUser(user2);
groupGuest.addUser(user1);
user1.addGroup(groupAdmin);
user2.addGroup(groupAdmin);
user1.addGroup(groupGuest);
session.save(groupAdmin);
session.save(groupGuest);
session.getTransaction().commit();
session.close();
}
} Output of the program:Hibernate: insert into GROUPS (NAME) values (?)
Hibernate: insert into USERS (USERNAME, PASSWORD, EMAIL) values (?, ?, ?)
Hibernate: insert into USERS (USERNAME, PASSWORD, EMAIL) values (?, ?, ?)
Hibernate: insert into GROUPS (NAME) values (?)
Hibernate: insert into UsersGroups (GROUP_ID, USER_ID) values (?, ?)
Hibernate: insert into UsersGroups (GROUP_ID, USER_ID) values (?, ?)
Hibernate: insert into UsersGroups (GROUP_ID, USER_ID) values (?, ?)
Result in the groups table:
Result in the users table:
Result in the UsersGroups table:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.