Hibernate One-to-Many Association Annotations Example
- Details
- Written by Nam Ha Minh
- Last Updated on 30 November 2023   |   Print Email
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:
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):
- Hibernate 4.2.7.SP1
- JDK 7
- Eclipse IDE 4.3 (Kepler)
- Maven 3
- MySQL Community Server 5.5.23
- MySQL Connector Java driver 5.1.26
Of course you can use similar versions. Here’s the summary of steps which we are going to follow:
Table of content:
- Creating Database and Tables
- Creating Maven-Eclipse Project
- Annotating Model Classes for One-to-Many Association
- Writing Hibernate Configuration File
- 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:
2. Creating Maven-Eclipse Project
In Eclipse IDE, create a Maven project named HibernateOne2ManyAnnotationsExample with the following 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:
Result in the product table:
You can also learn by following this video:
Related Hibernate One-to-Many Tutorials:
- Hibernate One-to-Many Association on Join Table Annotations Example
- Hibernate One-to-Many Using Join Table XML Mapping Example
- Hibernate One-to-Many XML Mapping Example
Other Hibernate Tutorials:
- Java Hibernate JPA Annotations Tutorial for Beginners
- Hibernate Hello World Tutorial for Beginners with Eclipse and MySQL
- Hibernate One-to-One Association on Primary Key Annotations Example
- Hibernate Many-to-Many Association with Extra Columns in Join Table Example
- Hibernate Enum Type Mapping Example
- Hibernate Binary Data and BLOB Mapping Example
- Hibernate Query Language (HQL) Example
- Java Hibernate Reverse Engineering Tutorial with Eclipse and MySQL
- Hibernate Basics - 3 ways to delete an entity from the datastore
Comments
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
Exception in thread "main" org.hibernate.HibernateException: /hibernate.cfg.xml
Actually you didn't specify where to put it.
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?
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