What is the difference between JOIN and JOIN FETCH when using JPA and Hibernate
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
In the world of Java Persistence API (JPA) and Hibernate, retrieving data from a database is a common task, and how you fetch the data can significantly affect your application's performance and behavior. Two of the terms you often encounter when dealing with database operations in JPA are JOIN and JOIN FETCH. While they might seem similar at a glance, they serve different purposes and act differently under the hood.
Understanding JOIN
JOIN is used to retrieve data from multiple tables based on a defined relationship between them. Generally, a JOIN operation does not fetch the associated entities or collections as part of the initial SQL query unless explicitly told to do so. Instead, this operation is about bringing together data from different tables based on some form of association or condition that links these tables.
In JPA and Hibernate, using JOIN in a JPQL (Java Persistence Query Language) or Criteria API query signifies that you want to join tables based on their defined relationships, like one-to-many, many-to-one, or many-to-many. Here, you're typically involved in a scenario where referencing the navigation capability of entities across their associations in your queries is necessary, rather than fetching the associated data per se.
Understanding JOIN FETCH
On the other hand, JOIN FETCH does more than merely joining tables; it fetches the associated entities as part of the same initial query. This technique is particularly useful and crucial for solving the N + 1 select problem in Hibernate. When you use JOIN FETCH, Hibernate generates SQL that not only joins the tables but also selects all columns from the associated tables, thus fetching all data required to populate the associated entity.
The advantage of using JOIN FETCH is that it helps in loading the related entities eagerly in one shot, which can significantly improve performance by reducing the number of required database roundtrips. This is essential when dealing with a hierarchical or complex object graph wherein accessing a top-level entity necessitates access to several related entities.
Example Comparison
Consider a situation where you have an Order entity and each Order has multiple Product entities associated with it through a one-to-many relationship. Here’s how you might use JOIN and JOIN FETCH:
- Using
JOIN:
This query simply joins the Order table and the Product table through the defined relationship and filters orders including a product named 'Gadget'. It will not fetch product details like price, quantity, etc., unless accessed explicitly, which would result in additional SQL queries (the N + 1 problem).
- Using
JOIN FETCH:
This query not only joins Order with Product but also fetches all products associated with the order of ID 123. It ensures that products are fetched in the same query, thus avoiding the N + 1 problem.
Key Differences Summarized
| Aspect | JOIN | JOIN FETCH |
| Primary Purpose | To join tables based on relationships | To fetch associated entities directly |
| SQL Generation | Does not include related entities' columns in SELECT clause | Includes related entities' columns in SELECT clause |
| Solves N + 1 Problem | No | Yes |
| When to Use | When no immediate need to use the associated entities directly | When associated entities are needed immediately post-query |
| Performance Impact | Might be less upfront but can lead to performance issues due to subsequent queries | Higher upfront cost but prevents further DB roundtrips, hence often more efficient |
When to Choose Which?
The choice between JOIN and JOIN FETCH depends significantly on your specific use case. If you need to utilize data from related entities right after the initial query and are dealing with a relatively small set of data, JOIN FETCH can be more efficient. However, if you are only interested in the entities from the primary table and might conditionally touch the associated entities, a standard JOIN would suffice.
Understanding the different implications of using JOIN versus JOIN FETCH in JPQL and Hibernate is crucial for optimized data access strategies and can lead to more performant applications.

