Ultimate Guide - Association Mappings with JPA and Hibernate (2024)

Take your skills to the next level!

The Persistence Hub is the place to be for every Java developer. It gives you access to all my premium video courses, monthly Java Persistence News, monthly coding problems, and regular expert sessions.

Join the Persistence Hub!

Association mappings are one of the key features of JPA and Hibernate. They model the relationship between two database tables as attributes in your domain model. That allows you to easily navigate the associations in your domain model and JPQL or Criteria queries.

JPA and Hibernate support the same associations as you know from your relational database model. You can use:

  • one-to-one associations,
  • many-to-one associations and
  • many-to-many associations.

You can map each of them as a uni- or bidirectional association. That means you can either model them as an attribute on only one of the associated entities or on both. That has no impact on your database mapping, but it defines in which direction you can use the relationship in your domain model and JPQL or Criteria queries. I will explain that in more detail in the first example.

Many-to-One Associations

An order consists of multiple items, but each item belongs to only one order. That is a typical example for a many-to-one association. If you want to model this in your database model, you need to store the primary key of the Order record as a foreign key in the OrderItem table.

With JPA and Hibernate, you can model this in 3 different ways. You can either model it as a bidirectional association with an attribute on the Order and the OrderItem entity. Or you can model it as a unidirectional relationship with an attribute on the Order or the OrderItem entity.

Unidirectional Many-to-One Association

Let’s take a look at the unidirectional mapping on the OrderItem entity first. The OrderItem entity represents the many side of the relationship and the OrderItem table contains the foreign key of the record in the Order table.

As you can see in the following code snippet, you can model this association with an attribute of type Order and a @ManyToOne annotation. The Order order attribute models the association, and the annotation tells Hibernate how to map it to the database.

@Entitypublic class OrderItem {@ManyToOneprivate Order order;…}

That is all you need to do to model this association. By default, Hibernate generates the name of the foreign key column based on the name of the relationship mapping attribute and the name of the primary key attribute. In this example, Hibernate would use a column with the name order_id to store the foreign key to the Order entity.

If you want to use a different column, you need to define the foreign key column name with a @JoinColumn annotation. The example in the following code snippet tells Hibernate to use the column fk_order to store the foreign key.

@Entitypublic class OrderItem {@ManyToOne@JoinColumn(name = “fk_order”)private Order order;…}

You can now use this association in your business code to get the Order for a given OrderItem and to add or remove an OrderItem to or from an existing Order.

Order o = em.find(Order.class, 1L);OrderItem i = new OrderItem();i.setOrder(o);em.persist(i);

That’s all about the mapping of unidirectional many-to-one associations for now. If you want to dive deeper, you should take a look at FetchTypes. I explained them in detail in my Introduction to JPA FetchTypes.

But now, let’s continue with the association mappings and talk about unidirectional one-to-many relationships next. As you might expect, the mapping is very similar to this one.

Unidirectional One-to-Many Association

The unidirectional one-to-many relationship mapping is not very common. In the example of this post, it only models the association on the Order entity and not on the OrderItem.

The basic mapping definition is very similar to the many-to-one association. It consist of the List items attribute which stores the associated entities and a @OneToMany association.

@Entitypublic class Order {@OneToManyprivate List<OrderItem> items = new ArrayList<OrderItem>();…}

But this is most likely not the mapping you’re looking for because Hibernate uses an association table to map the relationship. If you want to avoid that, you need to use a @JoinColumn annotation to specify the foreign key column.

The following code snippet shows an example of such a mapping. The @JoinColumn annotation tells Hibernate to use the fk_order column in the OrderItem table to join the two database tables.

@Entitypublic class Order {@OneToMany@JoinColumn(name = “fk_order”)private List<OrderItem> items = new ArrayList<OrderItem>();…}

You can now use the association in your business code to get all OrderItems of an Order and to add or remove an OrderItem to or from an Order.

Order o = em.find(Order.class, 1L);OrderItem i = new OrderItem();o.getItems().add(i);em.persist(i);

Bidirectional Many-to-One Associations

The bidirectional Many-to-One association mapping is the most common way to model this relationship with JPA and Hibernate. It uses an attribute on the Order and the OrderItem entity. This allows you to navigate the association in both directions in your domain model and your JPQL queries.

The mapping definition consists of 2 parts:

  • the to-many side of the association which owns the relationship mapping and
  • the to-one side which just references the mapping

Let’s take a look at the owning side first. You already know this mapping from the unidirectional Many-to-One association mapping. It consists of the Order order attribute, a @ManyToOne annotation and an optional @JoinColumn annotation.

@Entitypublic class OrderItem {@ManyToOne@JoinColumn(name = “fk_order”)private Order order;…}

The owning part of the association mapping already provides all the information Hibernate needs to map it to the database. That makes the definition of the referencing part simple. You just need to reference the owning association mapping. You can do that by providing the name of the association-mapping attribute to the mappedBy attribute of the @OneToMany annotation. In this example, that’s the order attribute of the OrderItem entity.

@Entitypublic class Order {@OneToMany(mappedBy = “order”)private List<OrderItem> items = new ArrayList<OrderItem>();…}

You can now use this association in a similar way as the unidirectional relationships I showed you before. But adding and removing an entity from the relationship requires an additional step. You need to update both sides of the association.

Order o = em.find(Order.class, 1L);OrderItem i = new OrderItem();i.setOrder(o);o.getItems().add(i);em.persist(i);

That is an error-prone task, and a lot of developers prefer to implement it in a utility method which updates both entities.

@Entitypublic class Order {…public void addItem(OrderItem item) {this.items.add(item);item.setOrder(this);}…}

That’s all about many-to-one association mapping for now. You should also take a look at FetchTypes and how they impact the way Hibernate loads entities from the database. I get into detail about them in my Introduction to JPA FetchTypes.

Many-to-Many Associations

Many-to-Many relationships are another often used association type. On the database level, it requires an additional association table which contains the primary key pairs of the associated entities. But as you will see, you don’t need to map this table to an entity.

A typical example for such a many-to-many association are Products and Stores. Each Store sells multiple Products and each Product gets sold in multiple Stores.

Similar to the many-to-one association, you can model a many-to-many relationship as a uni- or bidirectional relationship between two entities.

But there is an important difference that might not be obvious when you look at the following code snippets. When you map a many-to-many association, you should use a Set instead of a List as the attribute type. Otherwise, Hibernate will take a very inefficient approach to remove entities from the association. It will remove all records from the association table and re-insert the remaining ones. You can avoid that by using a Set instead of a List as the attribute type.

OK let’s take a look at the unidirectional mapping first.

Unidirectional Many-to-Many Associations

Similar to the previously discussed mappings, the unidirectional many-to-many relationship mapping requires an entity attribute and a @ManyToMany annotation. The attribute models the association and you can use it to navigate it in your domain model or JPQL queries. The annotation tells Hibernate to map a many-to-many association.

Let’s take a look at the relationship mapping between a Store and a Product. The Set products attribute models the association in the domain model and the @ManyToMany association tells Hibernate to map it as a many-to-many association.

And as I already explained, please note the difference to the previous many-to-one mappings. You should map the associated entities to a Set instead of a List.

@Entitypublic class Store {@ManyToManyprivate Set<Product> products = new HashSet<Product>();…}

If you don’t provide any additional information, Hibernate uses its default mapping which expects an association table with the name of both entities and the primary key attributes of both entities. In this case, Hibernate uses the Store_Product table with the columns store_id and product_id.

You can customize that with a @JoinTable annotation and its attributes joinColumns and inverseJoinColumns. The joinColumns attribute defines the foreign key columns for the entity on which you define the association mapping. The inverseJoinColumns attribute specifies the foreign key columns of the associated entity.

The following code snippet shows a mapping that tells Hibernate to use the store_product table with the fk_product column as the foreign key to the Product table and the fk_store column as the foreign key to the Store table.

@Entitypublic class Store {@ManyToMany@JoinTable(name = “store_product”, joinColumns = { @JoinColumn(name = “fk_store”) }, inverseJoinColumns = { @JoinColumn(name = “fk_product”) })private Set<Product> products = new HashSet<Product>();…}

That’s all you have to do to define an unidirectional many-to-many association between two entities. You can now use it to get a Set of associated entities in your domain model or to join the mapped tables in a JPQL query.

Store s = em.find(Store.class, 1L);Product p = new Product();s.getProducts().add(p);em.persist(p);

Bidirectional Many-to-Many Associations

The bidirectional relationship mapping allows you to navigate the association in both directions. And after you’ve read the post this far, you’re probably not surprised when I tell you that the mapping follows the same concept as the bidirectional mapping of a many-to-one relationship.

One of the two entities owns the association and provides all mapping information. The other entity just references the association mapping so that Hibernate knows where it can get the required information.

Let’s start with the entity that owns the relationship. The mapping is identical to the unidirectional many-to-many association mapping. You need an attribute that maps the association in your domain model and a @ManyToMany association. If you want to adapt the default mapping, you can do that with a @JoinColumn annotation.

@Entitypublic class Store {@ManyToMany@JoinTable(name = “store_product”, joinColumns = { @JoinColumn(name = “fk_store”) }, inverseJoinColumns = { @JoinColumn(name = “fk_product”) })private Set<Product> products = new HashSet<Product>();…}

The mapping for the referencing side of the relationship is a lot easier. Similar to the bidirectional many-to-one relationship mapping, you just need to reference the attribute that owns the association.

You can see an example of such a mapping in the following code snippet. The Set<Product> products attribute of the Store entity owns the association. So, you only need to provide the Stringproducts” to the mappedBy attribute of the @ManyToMany annotation.

@Entitypublic class Product{@ManyToMany(mappedBy=”products”)private Set<Store> stores = new HashSet<Store>();…}

That’s all you need to do to define a bidirectional many-to-many association between two entities. But there is another thing you should do to make it easier to use the bidirectional relationship.

You need to update both ends of a bidirectional association when you want to add or remove an entity. Doing that in your business code is verbose and error-prone. It’s, therefore, a good practice to provide helper methods which update the associated entities.

@Entitypublic class Store {public void addProduct(Product p) {this.products.add(p);p.getStores().add(this);}public void removeProduct(Product p) {this.products.remove(p);p.getStores().remove(this);}…}

OK, now we’re done with the definition of the many-to-many association mappings. Let’s take a look at the third and final kind of association: The one-to-one relationship.

One-to-One Associations

One-to-one relationships are rarely used in relational table models. You, therefore, won’t need this mapping too often. But you will run into it from time to time. So it’s good to know that you can map it in a similar way as all the other associations.

An example for a one-to-one association could be a Customer and the ShippingAddress. Each Customer has exactly one ShippingAddress and each ShippingAddress belongs to one Customer. On the database level, this mapped by a foreign key column either on the ShippingAddress or the Customer table.

Let’s take a look at the unidirectional mapping first.

Unidirectional One-to-One Associations

As in the previous unidirectional mapping, you only need to model it for the entity for which you want to navigate the relationship in your query or domain model. Let’s say you want to get from the Customer to the ShippingAddress entity.

The required mapping is similar to the previously discussed mappings. You need an entity attribute that represents the association, and you have to annotate it with an @OneToOne annotation.

When you do that, Hibernate uses the name of the associated entity and the name of its primary key attribute to generate the name of the foreign key column. In this example, it would use the column shippingaddress_id. You can customize the name of the foreign key column with a @JoinColumn annotation. The following code snippet shows an example of such a mapping.

@Entitypublic class Customer{@OneToOne@JoinColumn(name = “fk_shippingaddress”)private ShippingAddress shippingAddress;…}

That’s all you need to do to define a one-to-one association mapping. You can now use it in your business to add or remove an association, to navigate it in your domain model or to join it in a JPQL query.

Customer c = em.find(Customer.class, 1L);ShippingAddress sa = c.getShippingAddress();

Bidirectional One-to-One Associations

The bidirectional one-to-one relationship mapping extends the unidirectional mapping so that you can also navigate it in the other direction. In this example, you also model it on the ShippingAddress entity so that you can get the Customer for a giving ShippingAddress.

Similar to the previously discussed bidirectional mappings, the bidirectional one-to-one relationship consists of an owning and a referencing side. The owning side of the association defines the mapping, and the referencing one just links to that mapping.

The definition of the owning side of the mapping is identical to the unidirectional mapping. It consists of an attribute that models the relationship and is annotated with a @OneToOne annotation and an optional @JoinColumn annotation.

@Entitypublic class Customer{@OneToOne@JoinColumn(name = “fk_shippingaddress”)private ShippingAddress shippingAddress;…}

The referencing side of the association just links to the attribute that owns the relationship. Hibernate gets all information from the referenced mapping, and you don’t need to provide any additional information. You can define that with the mappedBy attribute of the @OneToOne annotation. The following code snippet shows an example of such a mapping.

@Entitypublic class ShippingAddress{@OneToOne(mappedBy = “shippingAddress”)private Customer customer;…}

Summary

The relational table model uses many-to-many, many-to-one and one-to-one associations to model the relationship between database records. You can map the same relationships with JPA and Hibernate, and you can do that in an unidirectional or bidirectional way.

The unidirectional mapping defines the relationship only on 1 of the 2 associated entities, and you can only navigate it in that direction. The bidirectional mapping models the relationship for both entities so that you can navigate it in both directions.

The concept for the mapping of all 3 kinds of relationships is the same.

If you want to create an unidirectional mapping, you need an entity attribute that models the association and that is annotated with a @ManyToMany, @ManyToOne, @OneToMany or @OneToOne annotation. Hibernate will generate the name of the required foreign key columns and tables based on the name of the entities and their primary key attributes.

The bidirectional associations consist of an owning and a referencing side. The owning side of the association is identical to the unidirectional mapping and defines the mapping. The referencing side only links to the attribute that owns the association.

Ultimate Guide - Association Mappings with JPA and Hibernate (2024)

FAQs

Can I use JPA and Hibernate together? ›

It guarantees that data is stored and retrieved from the database in accordance with the mappings. Hibernate extends JPA with extra functionality. But, relying on them would bind you to Hibernate. You cannot switch to another JPA implementation, such as Toplink.

What is the relationship between Hibernate and JPA? ›

Java Persistence API (JPA) and Hibernate are both Java frameworks that are widely used to map objects to relational databases. One of the key features of these frameworks is the ability to define relationships between entities, such as one-to-many, many-to-many, many-to-one, and one-to-one.

How to map calculated properties with JPA and Hibernate? ›

You have three options:
  1. either you are calculating the attribute using a @Transient method.
  2. you can also use @PostLoad entity listener.
  3. or you can use the Hibernate specific @Formula annotation.
Jun 6, 2010

What is association mapping in JPA? ›

Association mappings are one of the key features of JPA and Hibernate. They model the relationship between two database tables as attributes in your domain model. That allows you to easily navigate the associations in your domain model and JPQL or Criteria queries.

How to join two unrelated entities with JPA and Hibernate? ›

If you need to join two unrelated entities, then you should upgrade to at least Hibernate 5.1. Otherwise, if you don't want to use an equijoin, you can no longer use JPQL or HQL. For older versions of Hibernate, if you need an OUTER JOIN for your unrelated entities, then you can only do it using native SQL queries.

Which is faster JPA or Hibernate? ›

Even if JPA comes with its own API on top of Hibernate, this additional layer introduces no overhead. The execution times of Spring Data JPA insertions start from about 2 times more than Hibernate and JPA for 1000 records to about 3.5 times more for 50000 records.

What is bidirectional mapping in JPA? ›

In Spring Data JPA, a bidirectional one-to-many relationship involves two entities where one entity has a collection that holds multiple instances of another entity. This relationship is bidirectional, meaning that each entity is aware of its relationship with the other.

What is the best way to map one to one JPA? ›

As I explained in this article, the best way to map the @OneToOne association is using the @MapsId annotation on the child side. Notice that we are using both the @MapsId and the @JoinColumn annotation to instruct Hibernate that the Foreign Key column referencing the Post entity is the PostDetails identifier column.

What is the best way to map one to many Hibernate? ›

Among all , Bidirectional `@OneToMany` association is the best way to map a one-to-many database relationship. The hibernate association classified into One-to-One , One-to-Many/Many-to-One and Many-to-Many . The direction of a relationship can be either bidirectional or unidirectional.

How many types of association mapping are possible in Hibernate? ›

Association Mappings
Sr.No.Mapping type & Description
1Many-to-One Mapping many-to-one relationship using Hibernate
2One-to-One Mapping one-to-one relationship using Hibernate
3One-to-Many Mapping one-to-many relationship using Hibernate
4Many-to-Many Mapping many-to-many relationship using Hibernate

What are the steps in association mapping? ›

Five main steps exist for the association studies: 1) selection of the population's samples, 2) determination of the level and influence of the structure population on the sample, 3) phenotypic characterization of the population for the interest trait, 4) population genotyping for regions/candidate genes candidates or ...

How to achieve mapping in Hibernate? ›

Define Hibernate Mapping File

The <map> element will be used to define the rule for the Map used. The mapping document is an XML document having <hibernate-mapping> as the root element which contains two <class> elements corresponding to each class.

Does Hibernate support JPA? ›

Hibernate, being a JPA provider, offers additional features beyond the JPA specification, which can affect performance differently.

Can we use Hibernate without JPA? ›

Yes, Hibernate can be used independently of JPA, leveraging its native APIs and features like Hibernate Query Language (HQL).

What should I learn first, JPA or Hibernate? ›

So, if you're looking for more control over your database interactions, Hibernate is a good choice, while if you want a simpler and more opinionated approach, Spring Data JPA might be a better fit.

How to use JPA and Hibernate in Spring Boot? ›

JPA and Hibernate in 10 Steps with H2
  1. Step 1 : Object Relational Impedence Mismatch - Understanding the problem that JPA solves.
  2. Step 2 : World before JPA - JDBC, Spring JDBC and myBatis.
  3. Step 3 : Introduction to JPA.
  4. Step 4 : Creating a JPA Project using Spring Initializr.
  5. Step 5 : Defining a JPA Entity - User.
Mar 15, 2023

References

Top Articles
Usher concert postponed hours before tour opener in Atlanta, more shows pushed
Parkeren Hilversum | Reserveren vanaf €15 per dag | Q-Park
Jennifer Riordan Net Worth: A Comprehensive Look At Her Life And Legacy
scotty rasmussen paternity court
Moonrise Tonight Near Me
Rocket League Tracker Mmr Ranks
Po Box 6726 Portland Or 97228
Kitchen Song Singer Violet Crossword
Blind Guardian - The God Machine Review • metal.de
Ironman Kona Tracker
Get Got Lyrics
Best Amsterdam Neighborhoods for Expats: Top 9 Picks
Www.burlingtonfreepress.com Obituaries
Best 2 Player Tycoons To Play With Friends in Roblox
Suman Gharti on LinkedIn: Yashoda [2022] Hindi Dubbed Full Movie In 4K UHD | Samantha, Unni…
Craigslist North Platte Nebraska
Dickinson Jewelers Prince Frederick Md
Ip Address Issue Nad 3303
Forest | Definition, Ecology, Types, Trees, Examples, & Facts
Liquor Barn Redding
Elm Nychhc Org
How Much Does Costco Gas Cost Today? Snapshot of Prices Across the U.S. | CostContessa
We analyzed every QAnon post on Reddit. Here’s who QAnon supporters actually are.
Jacksonville Nc Skipthegames
افضل موقع سكسي عربي
Frequently Asked Questions | Google Fiber
Gw2 Blue Prophet Shard
Ottumwa Evening Post Obits
Lids Locker Room Vacaville Photos
Watch ESPN - Stream Live Sports & ESPN Originals
Lg Un9000 Review Rtings
Why Zero Raised to the Zero Power is defined to be One « Mathematical Science & Technologies
Language levels - Dutch B1 / 2 –What do these language levels mean? - Learn Dutch Online
Https://Gw.mybeacon.its.state.nc.us/App
Jami Lafay Gofundme
Envision Okta Sign In
Charlotte North Carolina Craigslist Pets
Busty Bruce Lee
Rush Copley Swim Lessons
The Untold Truth Of 'Counting Cars' Star - Danny Koker
Best Pizza In Ft Myers
Henkels And Mccoy Pay Stub Portal
Jacksonville Jaguars should be happy they won't see the old Deshaun Watson | Gene Frenette
Craigslist Farm And Garden Reading Pa
Apartments for Rent in Atlanta, GA - Home Rentals | realtor.com®
Oriley Auto Parts Hours
2022 Basketball 247
Gen 50 Kjv
55Th And Kedzie Elite Staffing
5 Pros & Cons of Massage Envy (VS Independent Massage Therapists)
Why Did Anthony Domol Leave Fox 17
Carenow Urgent Care - Eastchase Fort Worth Photos
Latest Posts
Article information

Author: Kieth Sipes

Last Updated:

Views: 5359

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Kieth Sipes

Birthday: 2001-04-14

Address: Suite 492 62479 Champlin Loop, South Catrice, MS 57271

Phone: +9663362133320

Job: District Sales Analyst

Hobby: Digital arts, Dance, Ghost hunting, Worldbuilding, Kayaking, Table tennis, 3D printing

Introduction: My name is Kieth Sipes, I am a zany, rich, courageous, powerful, faithful, jolly, excited person who loves writing and wants to share my knowledge and understanding with you.