In this Hibernate tutorial, we will learn how to use XML to map a one-to-many association on join table in relational database with Java objects. The following entity relationship diagram depicts the association:

 One to Many on a Join Table entity relationship

One-to-Many association on a join table

Here, a category can contain from one to many occurrences of article. The CategoryArticle is the join table between them. Let’s see how to model this association in Hibernate framework.

The sample application in this tutorial was developed and tested in the following environment (of course you can use newer versions):

Table of content:

    1. Creating Database Tables
    2. Setting up an Eclipse Project
    3. Coding Hibernate Model Classes
    4. Writing Hibernate Mapping Files
    5. Writing Hibernate Configuration File
    6. Coding a Test Program

 

1. Creating Database Tables

Create a MySQL database called newsdb with three tables: category, article and CategoryArticle (join table), by executing the following script in MySQL Workbench’s SQL Editor:

CREATE DATABASE `newsdb`;

use newsdb;

CREATE TABLE `category` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY (`category_id`)
);


CREATE TABLE `article` (
  `article_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(70) NOT NULL,
  `description` varchar(250) NOT NULL,
  `keywords` varchar(150) NOT NULL,
  `content` text NOT NULL,
  PRIMARY KEY (`article_id`)
);


CREATE TABLE `categoryarticle` (
  `category_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  PRIMARY KEY (`category_id`,`article_id`),
  KEY `fk_category` (`category_id`),
  KEY `fk_article` (`article_id`),
  CONSTRAINT `fk_article` FOREIGN KEY (`article_id`) REFERENCES `article` (`article_id`),
  CONSTRAINT `fk_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`)
);

If you are using MySQL Command Line Client, type the following command:

source Path\To\The\Script\File\MySQLscript.sql

Create the MySQLscript.sql file from the above script or find it in the attached project. The database newsdb will have the following structure:

newsdb MySQL database structure

2. Setting up an Eclipse Project

Create a Java project in Eclipse IDE called HibernateOne2ManyJoinTableXMLExample with the following structure:

Hibernate one to many on join table eclipse project structure

We will create/add to this project the following files:

    • Model classes: Category.java and Article.java
    • Hibernate XML mapping files: Category.hbm.xmland Article.hbm.xml
    • Hibernate XML configuration file: hibernate.cfg.xml
    • Test program: ArticlesManager.java
    • Hibernate required JAR libraries and MySQL Connector Java driver:
      • hibernate-core-4.2.2.Final.jar
      • hibernate-commons-annotations-4.0.2.Final.jar
      • mysql-connector-java-5.1.25-bin.jar
      • jboss-transaction-api_1.1_spec-1.0.1.Final.jar
      • hibernate-jpa-2.0-api-1.0.1.Final.jar
      • jboss-logging-3.1.0.GA.jar
      • antlr-2.7.7.jar
      • dom4j-1.6.1.jar
      • javassist-3.15.0-GA.jar
    • MySQL script file: MySQLscript.sql

Find the Hibernate and MySQL jar files from their distribution archives.

 

3. Coding Hibernate Model Classes

Create two Java files Category.java and Article.java corresponding to the tables category and article:

File net\codejava\hibernate\Category.java:

package net.codejava.hibernate;

import java.util.Set;

public class Category {

	private long id;
	private String name;

	private Set<Article> articles;

	public Category() {
	}

	public Category(String name) {
		this.name = name;
	}

	// getters and setters...
}

 

File net\codejava\hibernate\Article.java:

package net.codejava.hibernate;

public class Article {
	private long id;
	private String title;
	private String description;
	private String keywords;
	private String content;

	private Category category;

	public Article() {
	}

	public Article(String title, String description, String keywords,
			String content, Category category) {
		this.title = title;
		this.description = description;
		this.keywords = keywords;
		this.content = content;
		this.category = category;
	}

	// getters and setters...
}

NOTES: The Category class has a set of articles and the Article class has a reference to its category. This is a typical configuration for a bidirectional one-to-many association. And note that we don’t have to write model class for the join table.

 

4. Writing Hibernate Mapping Files

Create two Hibernate mapping files Category.hbm.xml and Article.hbm.xml with the following content:

File net\codejava\hibernate\Category.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="Category" table="CATEGORY">
		<id name="id" column="CATEGORY_ID">
			<generator class="native"/>
		</id>
		<property name="name" column="NAME" />

		<set name="articles" table="CategoryArticle" cascade="all">
			<key column="CATEGORY_ID" not-null="true" />
			<many-to-many column="ARTICLE_ID" class="Article" unique="true"/>
		</set>
	</class>	
</hibernate-mapping>

 

File net\codejava\hibernate\Article.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="Article" table="ARTICLE">
		<id name="id" column="ARTICLE_ID">
			<generator class="native"/>
		</id>
		<property name="title" column="TITLE" />
		<property name="description" column="DESCRIPTION" />
		<property name="keywords" column="KEYWORDS" />
		<property name="content" column="CONTENT" />

		<join table="CategoryArticle" inverse="true">
			<key column="ARTICLE_ID"/>
			<many-to-one name="category" column="CATEGORY_ID" not-null="true"/>
		</join>
	</class>	
</hibernate-mapping>

 

NOTES:

    • We specify the join table CategoryArticle for both sides, in the <set> element of the Category.hbm.xml file and in the <join> element of the Article.hbm.xml file.
    • Category.hbm.xml: The attribute cascade=”all” tells Hibernate to update changes to the children (article) automatically when the parent (category) has changed.
    • Article.hbm.xml: The attribute inverse=”true” tells Hibernate that the relationship owner is on the reverse side (the join table). Specifying this attribute is required for a one-to-many association.

 

5. Writing Hibernate Configuration File

Write code for the Hibernate configuration file (hibernate.cfg.xml) as follows:

<?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/newsdb</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/Category.hbm.xml"/>
    <mapping resource="net/codejava/hibernate/Article.hbm.xml"/>
      
  </session-factory>
</hibernate-configuration>

You may need to change the username and password according to your MySQL account.

 

6. Coding a Test Program

To wire all the above pieces together, create a test program that persists some sample data as follows:

package net.codejava.hibernate;

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

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

/**
 * This program demonstrates how to use Hibernate framework to manage 
 * a one-to-many association on a join table.
 * @author www.codejava.net
 *
 */
public class ArticlesManager {

	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();

		Category category = new Category("Hibernate Framework");

		Article articleOne = new Article("One-to-One Mapping",
				"One-to-One XML Mapping Tutorial", "Hibernate,One-to-One",
				"Content of One-to-One XML Mapping Tutorial", category);
		Article articleTwo = new Article("One-to-Many Mapping",
				"One-to-Many XML Mapping Tutorial", "Hibernate,One-to-Many",
				"Content of One-to-Many XML Mapping Tutorial", category);
		Article articleThree = new Article("Many-to-Many Mapping",
				"Many-to-Many XML Mapping Tutorial", "Hibernate,Many-to-Many",
				"Content of Many-to-Many XML Mapping Tutorial",	category);

		Set<Article> articles = new HashSet<Article>();
		articles.add(articleOne);
		articles.add(articleTwo);
		articles.add(articleThree);

		category.setArticles(articles);

		session.save(category);

		session.getTransaction().commit();
		session.close();
	}

}

 

Output of the program:

Hibernate: insert into CATEGORY (NAME) values (?)

Hibernate: insert into ARTICLE (TITLE, DESCRIPTION, KEYWORDS, CONTENT) values (?, ?, ?, ?)

Hibernate: insert into ARTICLE (TITLE, DESCRIPTION, KEYWORDS, CONTENT) values (?, ?, ?, ?)

Hibernate: insert into ARTICLE (TITLE, DESCRIPTION, KEYWORDS, CONTENT) values (?, ?, ?, ?)

Hibernate: insert into CategoryArticle (CATEGORY_ID, ARTICLE_ID) values (?, ?)

Hibernate: insert into CategoryArticle (CATEGORY_ID, ARTICLE_ID) values (?, ?)

Hibernate: insert into CategoryArticle (CATEGORY_ID, ARTICLE_ID) values (?, ?)

 

Result in the category table:

result records in category table

Result in the article table:

result records in article table

Result in the CategoryArticle table:

result records in CategoryArticle table

You can get the code examples on GitHub, or download the sample project attached below. 

 

Related Hibernate One-to-Many Tutorials:

 

Other Hibernate Tutorials:


About the Author:

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.



Attachments:
Download this file (HibernateOne2ManyJoinTableXMLExample.zip)HibernateOne2ManyJoinTableXMLExample.zip[Eclipse project]6400 kB

Add comment

   


Comments 

#5shashi2017-12-13 02:46
hey can you explain about and
Quote
#4Parshuram Patil2017-08-15 05:41
Hi,
Nice article.
As per the problem statement, one category has many Articles, then why there is many to many mapping in category.hbm.xml.

Can you please, help me in understanding.
Quote
#3Nam2014-01-08 08:24
Quoting gaurav :
sorry its my mistake but this code is not working it gives an error

What was the error? Could you post more details?
Quote
#2gaurav 2014-01-08 07:28
sorry its my mistake but this code is not working it gives an error
Quote
#1gaurav 2014-01-08 07:18
its an error, please change your code in join tag , mapping of many to many should be before join tag
Quote