Hibernate One To Many Relationship

Continuing from my post Spring MVC + Hibernate + MySQL Quick Start From Scratch, here is how to setup one to many relationship on Hibernate.

Let’s assume you want to add a new table called topping, each pizza can have several toppings (one to many relationship).

Pizza table
pizzatable

Topping table
topping table

First code the Topping entity class:


(name = "topping")
public class Topping {
  @Id
  
  private long id;
  
  private String name;
  
  
  (name = "pizza_id", referencedColumnName = "id")
  private Pizza pizza;

  // getters & setters..
}

Notice the usage of and annotation. This allows the owning Pizza to be queried from the Topping. This also says “in order to find pizza that owns this topping, have a look at pizza_id column on topping table, match it with id column on pizza table”

And let’s have a look at our modified Pizza entity class:


(name = "pizza")
public class Pizza {
  @Id  private long id;
  private String name;
  private double price;
  
  (mappedBy = "pizza", fetch = FetchType.LAZY)
  private List toppings;

  // getters & setters
}

This setups a bi-directional relationship where you can obtain list of toppings from a Pizza object, and the owning Pizza from a Topping object. The mappedBy attribute refers to the java property name of Pizza reference on the Topping class.

The FetchType.LAZY setting tells Hibernate not to bother populating the toppings unless we ask it to (this is handy to conserve memory if you have a long chains of relationships with thousands of objects on it).

Next if I want to list my pizzas with its topping, I can write following method on my DAO class:


public List findAllWithToppings() {
  Session session = sessionFactory.getCurrentSession();
  List pizzas = session.createQuery("select distinct p from Pizza as p left join fetch p.toppings").list();
  return pizzas;
}

The above hibernate query will roughly translate into following SQL:

select * from pizza p left outer join topping t on p.id = t.pizza_id;

Download the source code

git clone https:///gerrytan/pizzashop.git -b one_to_many

5 thoughts on “Hibernate One To Many Relationship”

  1. Excellent Tutorial. Now It would be nice to have a followup tutorial that shows how to do interactive inserts, updates and deletes using the DAO design pattern.

    Reply
  2. This is a great tutorial (mini-) series, and I hope to see more posts in this series. You’ve done a great job of explaining how to use Spring with Hibernate! This tutorial pretty much saved me from a ton of confusion!

    And now back to business: I left the findAll method unchanged and changed the toping list’s FetchType to FetchType.EAGER and hibernate fetched my toppings automagically. This way, even if my object/table structure ends up being rather complex, I won’t have to manually write Hibernate queries (which I’m not completely familiar with) to reflect the changes. I understand that it’s going to be slower than lazy fetching.

    My question is: how slow? (Note that I’m working on a University project, so it’s not going to be production code, but I’m asking in principle whether this is a bad thing; I am used to using Python/Flask + PeeWee, which does this as the default action)

    Reply
    1. There isn’t blanket answer to measure eager fetching performance. If say a pizza only have 4-5 toppings then eager would be fine. However if a pizza has a million toppings, then you might be (inadvertently) loading one million objects into your memory (in most cases this is bad).

  3. any idea or tutorial how to do a form with checkboxes in thymeleaf (many-to-many)? because it’s been a week i can’t get out this trouble and i think a form with checkboxes is very common in web development, but i can’t find anything working on the web

    Reply

Leave a Reply