This Hibernate tutorial will take you go through an example of mapping a one-to-many association using JPA annotations - an alternative to XML descriptor approach which is described in the Hibernate One-to-Many XML Mapping Example tutorial.

Let’s look at the following entity relationship diagram to recall about the one-to-many association:

one-to-many entity relationship

Here, the multiplicity between the two entities category and product is one-to-many, meaning that a category can have one or many products. This one-to-many association is constrained by the foreign key in the product table.

The following software programs and libraries are used in order to develop a sample Hibernate application that implements the one-to-many association above (you can use newer versions):

Of course you can use similar versions. Here’s the summary of steps which we are going to follow:

Table of content:

  1. Creating Database and Tables
  2. Creating Maven-Eclipse Project
  3. Annotating Model Classes for One-to-Many Association
  4. Writing Hibernate Configuration File
  5. Writing a Test Program

 

1. Creating Database and Tables

Execute the following MySQL script to create a database stockdb and two tables category and product:

create database stockdb;
use stockdb;

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

CREATE TABLE `product` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `description` varchar(512) NOT NULL,
  `price` float NOT NULL,
  `category_id` int(11) NOT NULL,
  PRIMARY KEY (`product_id`),
  KEY `fk_category` (`category_id`),
  CONSTRAINT `fk_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`)
);

The structure of the stockdb database would look like this:

stockdb database structure


2. Creating Maven-Eclipse Project

In Eclipse IDE, create a Maven project named HibernateOne2ManyAnnotationsExample with the following structure:

Hibernate One-to-Many Annotations project structure

This project consists of the following files:

  • Model classes: Category.java and Product.java
  • Hibernate XML configuration file: hibernate.cfg.xml
  • Test program: StockManager.java
  • Maven project: pom.xml

Note that when using annotations approach, the XML mapping files for the model classes are no longer needed. For JAR files of Hibernate and MySQL Connector/J, update the pom.xml file as follows:

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>net.codejava.hibernate</groupId>
  <artifactId>HibernateOne2ManyAnnotationsExample</artifactId>
  <version>1.0</version>
  <description>Example of a Hibernate one-to-many association mapping 
  	using annotations</description>
  <dependencies>
  	<dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-core</artifactId>
  		<version>4.2.7.SP1</version>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>5.1.26</version>
  	</dependency>
  </dependencies>  
</project>

And Maven will resolve related dependencies if any. 


3. Annotating Model Classes for One-to-Many Association

Create two model classes called Category.java and Product.java with the following source code:

File net\codejava\hibernate\Category.java:

package net.codejava.hibernate;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;


@Entity
@Table(name = "CATEGORY")
public class Category {

	private long id;
	private String name;

	private Set<Product> products;

	public Category() {
	}

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

	@Id
	@Column(name = "CATEGORY_ID")
	@GeneratedValue
	public long getId() {
		return id;
	}

	@OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
	public Set<Product> getProducts() {
		return products;
	}

	// other getters and setters...
}

 

File net\codejava\hibernate\Product.java:

package net.codejava.hibernate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "PRODUCT")
public class Product {
	private long id;
	private String name;
	private String description;
	private float price;

	private Category category;

	public Product() {
	}

	public Product(String name, String description, float price,
			Category category) {
		this.name = name;
		this.description = description;
		this.price = price;
		this.category = category;
	}

	@Id
	@Column(name = "PRODUCT_ID")
	@GeneratedValue
	public long getId() {
		return id;
	}

	@ManyToOne
	@JoinColumn(name = "CATEGORY_ID")
	public Category getCategory() {
		return category;
	}

	// other getters and setters...
}

Note that, the Category class has a set of Products, and the Product has a reference back to the Category.

And, as we can see, only JPA annotations are used to annotate the model classes. The @Entity, @Table, @Column, @Id and @GeneratedValue annotations are self-explanatory and easy to understand. They are the basic elements needed for annotating any entities in Hibernate, regardless of the association. We pay attention to the annotations that make the one-to-many association: @OneToMany, @ManyToOne and @JoinColumn. Let’s look at the code closely:

  • In the Category side:
    private Set<Product> products;
    
    @OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
    public Set<Product> getProducts() {
    	return products;
    }

    Here, the mappedBy attribute is mandatory, as it specifies that the one-to-many association is mapped by this side (Category); and the cascade attribute make sure Hibernate will save/update the products set when saving/updating this category.

  • In the Product side:
    private Category category;
    
    @ManyToOne
    @JoinColumn(name = "CATEGORY_ID")
    public Category getCategory() {
    	return category;
    }

    Here, the @JoinColumn annotation specifies the join column of the association. It is also mandatory.

Therefore, remember the key annotations are used for mapping a one-to-many association: @OneToMany, @ManyToOne and @JoinColumn.

 

Java Servlet, JSP and Hibernate course

Learn Java Servlet, JSP, Hibernate framework to build an eCommerce Website (with PayPal and credit card payment)


4. Writing Hibernate Configuration File

Configure database connection settings and mapping classes in the hibernate.cfg.xml file 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/stockdb</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 class="net.codejava.hibernate.Category"/>
    <mapping class="net.codejava.hibernate.Product"/>
      
  </session-factory>
</hibernate-configuration>


5. Writing a Test Program

So far we have finished the configuration part. Now, let’s write a test program (StockManager.java) with the following source code:

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 using JPA annotations in Hibernate
 * in order to implement a one-to-many association mapping.
 * @author www.codejava.net
 *
 */
public class StockManager {

	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("Computer");
		
		Product pc = new Product("DELL PC", "Quad-core PC", 1200, category);
		
		Product laptop = new Product("MacBook", "Apple High-end laptop", 2100, category);
		
		Product phone = new Product("iPhone 5", "Apple Best-selling smartphone", 499, category);
		
		Product tablet = new Product("iPad 3", "Apple Best-selling tablet", 1099, category);
		
		Set<Product> products = new HashSet<Product>();
		products.add(pc);
		products.add(laptop);
		products.add(phone);
		products.add(tablet);
		
		category.setProducts(products);
		
		session.save(category);
		
		session.getTransaction().commit();
		session.close();		
	}
}

Output of the program:

Hibernate: insert into CATEGORY (name) values (?)
Hibernate: insert into PRODUCT (CATEGORY_ID, description, name, price) values (?, ?, ?, ?)
Hibernate: insert into PRODUCT (CATEGORY_ID, description, name, price) values (?, ?, ?, ?)
Hibernate: insert into PRODUCT (CATEGORY_ID, description, name, price) values (?, ?, ?, ?)
Hibernate: insert into PRODUCT (CATEGORY_ID, description, name, price) values (?, ?, ?, ?)

Result in the category table:

records in category table

Result in the product table:

records in product table

 

You can also learn by following this video:

 

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 (HibernarteOne2ManyAnnotationsExample.zip)HibernarteOne2ManyAnnotationsExample.zip[Eclipse-Maven project]17 kB

Add comment

   


Comments 

#12kasereka2022-12-11 04:15
i really like your lesson brother keep on doing the great work.
please would mind help you us to know hwo to join to class pojo in to one pojo via annotation.
like there are tree class a,b and c then you want to join them all i mean a and c in b how do the notation will be done in b
Quote
#11Alejandro Barrero2018-08-29 09:11
StockManager doesn't work; i am getting
Exception in thread "main" org.hibernate.HibernateException: /hibernate.cfg.xml
Actually you didn't specify where to put it.
Quote
#10amitabh2018-06-14 09:18
Cont....

Category table:
Category_id Category_Name
1 Foods
2 Foods

Product table:
product_id category_id product_name
101 1 vegitable
102 2 Processed foods

So now how to map so that if category_name is Food it do not insert another row as food again and i can have multiple products under one category?
Quote
#9amitabh2018-06-14 09:12
One question here , There is one scenario where i used ur example, so for the first time i insert category_name as Foods (Category_id = 1) with product as vegitables. so it will insert first in category and then persist vegitable into product along with category id.
Now, i want add one more product (Processed foods) under same category (Food) but in this case it created one more category_id =2 it do not refer the exiting category and insert in product table as
Quote
#8Jervy2017-06-24 09:09
Im having problem with ServiceRegistryBuilder class. it seems that I need another libraries. what should I do?
Quote