I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

This quick Hibernate tutorial will take you through an example of one-to-many mapping using JPA annotations – an alternative to the XML descriptor approach.

In simple terms, one-to-many mapping means that one row in a table is mapped to multiple rows in another table.

2. Description

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

For this example, we will implement a Cart system, where we have a table for Cart and another table for Items. A Cart can have multiple items, so here we have a one-to-many mapping with cart_id as a primary key in the Cart table and this association is constrained by the foreign key in the Items table.

The code snippet below shows the implementation of a @OneToMany mapping of Cart class to the ItemEntry object, simply put, it means that a single Cart object can be associated with multiple ItemEntry objects:

public class Cart {

    //...     
 
    @OneToMany(mappedBy="cart")
    private Set<ItemEntry> items;
	
    //...
}

This bidirectional relationship between objects means that we are able to access Object A from Object B, and Object B from Object A. The mappedBy property is what we use to tell Hibernate which variable we are using to represent the parent class in our child class.

The following technologies and libraries are used in order to develop a sample Hibernate application that implements one-to-many association:

  • JDK 1.8 or later
  • Hibernate 4 or later
  • Maven 3 or later
  • MySQL Server 5.6 or later

3. Setup

3.1. Database Setup

Below is our database script for Cart and Items tables. We use the foreign key constraint for one-to-many mapping:

CREATE TABLE `Cart` (
  `cart_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

CREATE TABLE `Items` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `cart_id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `cart_id` (`cart_id`),
  CONSTRAINT `items_ibfk_1` FOREIGN KEY (`cart_id`) REFERENCES `Cart` (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

Our database setup is ready, let’s move on to creating the Hibernate example project.

3.2. Maven Dependencies

We will then add the Hibernate and MySQL driver dependencies to our pom.xml file.The Hibernate dependency uses JBoss logging and it automatically gets added as transitive dependencies:

  • Hibernate version 5.2.7.Final
  • MySQL driver version 6.0.5

Please visit the Maven central repository for the latest versions of Hibernate and the MySQL dependencies.

3.3. Hibernate Configuration

Here is the configuration of Hibernate:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/setup</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.show_sql">true</property>
    </session-factory>
</hibernate-configuration>

3.4. HibernateAnnotationUtil Class

With the HibernateAnnotationUtil class, we just need to reference the new Hibernate configuration file:

private static SessionFactory sessionFactory;

private SessionFactory buildSessionFactory() {
     
    Configuration configuration = new Configuration();
    configuration.configure("hibernate-annotation.cfg.xml");
    System.out.println("Hibernate Annotation Configuration loaded");
        	
    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
      .applySettings(configuration.getProperties()).build();
    System.out.println("Hibernate Annotation serviceRegistry created");
        	
    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        	
    return sessionFactory;
}	

public SessionFactory getSessionFactory() {
    if(sessionFactory == null) sessionFactory = buildSessionFactory();
    return sessionFactory;
}

4. The Models

The mapping related configurations will be done using JPA annotations in the model classes:

@Entity
@Table(name="CART")
public class Cart {

    //...

    @OneToMany(mappedBy="cart")
    private Set<ItemEntry> items;
	
    // getters and setters
}

Please note that the @OneToMany annotation is used to define the property in Items class that will be used to map the mappedBy variable. That’s why we have a property named “cart” in the Items class:

@Entity
@Table(name="ITEMS")
public class ItemEntry {
    
    //...
    @ManyToOne
    @JoinColumn(name="cart_id", nullable=false)
    private Cart cart;

    public ItemEntry() {}
    
    // getters and setters
}

It is importing to note that the @ManyToOne annotation is associated with Cart class variable. @JoinColumn annotation references the mapped column.

5. In Action

In the test program, we are creating a class with a main() method for getting the Hibernate Session and saving the model objects into the database implementing the one-to-many association:

sessionFactory = HibernateAnnotationUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
System.out.println("Session created");
	    
tx = session.beginTransaction();

session.save(cart);
session.save(item1);
session.save(item2);
	    
tx.commit();
System.out.println("Cart ID=" + cart.getId());
System.out.println("item1 ID=" + item1.getId()
  + ", Foreign Key Cart ID=" + item.getCart().getId());
System.out.println("item2 ID=" + item2.getId()
+ ", Foreign Key Cart ID=" + item.getCart().getId());

This is the output of our test program:

Session created
Hibernate: insert into CART values ()
Hibernate: insert into ITEMS (cart_id)
  values (?)
Hibernate: insert into ITEMS (cart_id)
  values (?)
Cart ID=7
item1 ID=11, Foreign Key Cart ID=7
item2 ID=12, Foreign Key Cart ID=7
Closing SessionFactory

6. Conclusion

We have seen how easy it is to implement the one-to-many relationship with the Hibernate ORM and MySQL database using JPA annotations.

The source code of this tutorial can be found over on GitHub.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS

Sort by:   newest | oldest | most voted
Sagar Kalburgi
Guest

Thanks for writing this blog! It was helpful