Associations with JPA and Hibernate


The handling of associations between entities and their underlying database records is one of the key strengths of JPA. It hides most of the technical complexity and enables you to concentrate on the business logic you want to implement.

At the same time, it's often the reason for performance problems. A seemingly small misconfiguration in your mapping definition or a missing optimization when loading your entities can cause lots of unexpected SQL statements.

You can easily avoid these issues, if you have a solid understanding of the mapping definitions, know when and why Hibernate executes additional queries and follow a few best practices. 

Association Mappings

The definition of a basic entity mapping is simple. It only requires an entity attribute and 1-2 annotations. On the right, you can see an example mapping of a standard many-to-one association mapping.

Based on this mapping, your persistence provider, e.g., Hibernate, knows the database tables and the foreign columns that represent the association in your table model. It then generates all the required SQL statements to fetch the association from the database and to persist all changes.

I explain all of these mappings in great details in the following article. If you don't have a lot of experience with the mapping of associations, you should start there.

Advanced Association Mappings

OK, let's take it one step further. Based on the basic mappings described in the previous article, you can model all kinds of associations. You can model self-referencing associations, persist additional attributes for each association record, define associations between more than 2 entities and much more.

Mapping Collections with Hibernate and JPA

JPA and Hibernate provide 3 main options to map a Collection. If it’s a Collection of other entities, you can model it as a to-many association. This is the most common mapping. But you can also map it as an @ElementCollection or as a basic type. In this article, I will show you all 3

Read More

Modeling self-referencing associations with Hibernate

When you model a hierarchical data structure, you often have to use self-referencing associations. Both ends of these associations are of the same type. In other words, the entity object on which the association is defined and the one the association references are of the same type. In your database, you model that using a

Read More

Ternary Associations – Modelling Associations between 3 Entities

An association between 3 entities is called a ternary association. A typical example is an association between an employee, the project they are working on, and their role in that project. If the role is a complex object, you might decide to model this as 3 entity classes. The association between them is the interesting

Read More

How to map an association as a java.util.Map

The java.util.List<SomeEntityClass> is the most common representation of a to-many association with JPA and Hibernate. But is it also the one that you want to use in your domain model? Does it fit your use cases or do you need smarter access to the associated elements? Let’s be honest, a simple java.util.List is good enough

Read More

Improve Usability and Avoid Performance Issues

If you want to use these different kinds of associations as efficient as possible, you also need to be familiar with JPA's FetchTypes, the side-effects of cascade operations, and Hibernate's handling of different Collection types.

How to Choose the Most Efficient Data Type for To-Many Associations – Bag vs. List vs. Set

Which data type should you use to map a to-many association with Hibernate? Is it better to use a Set or a List? That’s a very common question, and most developers are surprised when they look at the documentation and find out that these are not the only options. You can also use a Bag

Read More

Why you should avoid CascadeType.REMOVE for to-many associations and what to do instead

The CascadeTypes REMOVE and ALL, which includes REMOVE, provide a comfortable option to remove an entity together with all its child entities. But it creates several issues for to-many associations, and you should only use it for to-one relationships.

Read More

Entity Mappings: Introduction to JPA FetchTypes

The FetchType defines when Hibernate gets the related entities from the database, and it is one of the crucial elements for a fast persistence tier. In general, you want to fetch the entities you use in your business tier as efficiently as possible. But that’s not that easy. You either get all relationships with one query

Read More

Association Fetching

The way you fetch your associations often makes the difference between a blazingly fast application and huge performance problems. But don't worry, doing it right is much easier as you might think. As long as you use the FetchType.LAZY and initialize all required associations when you fetch your entity, you should avoid at least 90% of all performance problems.

How to Initialize Entity Associations with Spring Data JPA

When we’re talking about performance optimizations for Spring Data JPA, the handling of associations is always an important topic. Because Spring Data JPA is based on JPA and most often used with Hibernate, you can apply all the performance tuning concepts you can find here on the blog. The most important one is to use

Read More

Your 2 best options to fix Hibernate’s MultipleBagFetchException

You probably learned that you should use FetchType.LAZY for all of your associations. It ensures that Hibernate initializes an association when you use it and doesn’t spend any time getting data you don’t need. Unfortunately, this introduces a new issue. You now need to use a JOIN FETCH clause or an EntityGraph to fetch the

Read More

The best way to fetch an association defined by a subclass

EntityGraphs and JOIN FETCH clauses provide an easy and efficient way to fetch an entity and initialize its associations. But if you try to use it with a domain model that uses inheritance, you will quickly run into an issue: You can’t use this approach in a polymorphic query to fetch an association that’s defined

Read More

LazyInitializationException – What it is and the best way to fix it

The LazyInitializationException is one of the most common exceptions when working with Hibernate. There are a few easy ways to fix it. But unfortunately, you can also find lots of bad advice online. The proclaimed fixes often replace the exception with a hidden problem that will cause trouble in production. Some of them introduce performance

Read More

Entity Mappings: Introduction to JPA FetchTypes

The FetchType defines when Hibernate gets the related entities from the database, and it is one of the crucial elements for a fast persistence tier. In general, you want to fetch the entities you use in your business tier as efficiently as possible. But that’s not that easy. You either get all relationships with one query

Read More

5 ways to initialize lazy associations and when to use them

Lazy loading of associations between entities is a well established best practice in JPA. Its main goal is to retrieve only the requested entities from the database and load the related entities only if needed. That is a great approach if you only need the requested entities. But it creates additional work and can be

Read More

Best Practices

The easiest way to ensure that you applied the most important parts of all the things you learned in the previously mentioned articles is to follow common best practices. So, make sure to keep the following articles at hand and to check them regularly.

Best Practices for Many-to-Many Associations with Hibernate and JPA

Many-to-Many associations are one of the most commonly used associations with JPA and Hibernate. You can find lots of examples for them in the real world, and you can map them with JPA and Hibernate as a uni- or bidirectional association in your domain model. But you probably also know that these mappings provide several

Read More

Best Practices for Many-To-One and One-To-Many Association Mappings

When you model your database, you will most likely define several many-to-one or one-to-many associations. And it’s, of course, the same when you model your entities. It’s quite easy to do that with JPA and Hibernate. You just need an attribute that represents the association and annotate it with a @ManyToOne or @OneToMany association. But

Read More