Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Join Fetch for Optimization in Spring Boot
📖 Scenario: You are building a Spring Boot application that manages authors and their books. Each author can have multiple books. You want to fetch authors along with their books efficiently to avoid performance issues.
🎯 Goal: Learn how to use @Query with JOIN FETCH in Spring Data JPA to optimize fetching related entities in one query.
📋 What You'll Learn
Create an Author entity with a list of Book entities
Create a Spring Data JPA repository for Author
Add a configuration variable to control fetching behavior
Write a repository method using JOIN FETCH to fetch authors with their books in one query
💡 Why This Matters
🌍 Real World
Fetching related data efficiently is important in real-world applications to reduce database load and improve performance.
💼 Career
Understanding join fetch queries and Spring Data JPA repositories is essential for backend developers working with Spring Boot and relational databases.
Progress0 / 4 steps
1
Create Author and Book Entities
Create two entities: Author and Book. In Author, add a field List books with @OneToMany(mappedBy = "author"). In Book, add a field Author author with @ManyToOne. Use exact class and field names.
Spring Boot
Hint
Remember to use @Entity on both classes and map the relationship correctly with @OneToMany and @ManyToOne.
2
Add Repository Interface for Author
Create an interface AuthorRepository that extends JpaRepository<Author, Long>. Add a boolean variable fetchBooks in your service or config class to control whether to fetch books eagerly or lazily.
Spring Boot
Hint
Create the repository interface with the exact name AuthorRepository and extend JpaRepository<Author, Long>. Add the boolean variable fetchBooks exactly as shown.
3
Add Repository Method with Join Fetch
In AuthorRepository, add a method List<Author> findAllWithBooks() annotated with @Query that uses SELECT a FROM Author a JOIN FETCH a.books to fetch authors with their books in one query.
Spring Boot
Hint
Use @Query annotation with the exact JPQL query SELECT a FROM Author a JOIN FETCH a.books and method name findAllWithBooks().
4
Use the Join Fetch Method Conditionally
In your service class, write a method List<Author> getAuthors() that returns authorRepository.findAllWithBooks() if AuthorServiceConfig.fetchBooks is true, otherwise returns authorRepository.findAll(). Use exact method and variable names.
Spring Boot
Hint
Use the boolean fetchBooks to decide which repository method to call inside getAuthors().
Practice
(1/5)
1. What is the main purpose of using JOIN FETCH in Spring Boot JPA queries?
easy
A. To create a new table for the joined entities
B. To delete related entities automatically when the parent is deleted
C. To load related entities eagerly in a single query and avoid multiple database hits
D. To update related entities in batch
Solution
Step 1: Understand what JOIN FETCH does
JOIN FETCH tells JPA to load related entities eagerly in the same query instead of lazy loading them later.
Step 2: Recognize the performance benefit
This reduces the number of database queries, improving performance by avoiding the N+1 select problem.
Final Answer:
To load related entities eagerly in a single query and avoid multiple database hits -> Option C
Quick Check:
Join fetch = eager load related data [OK]
Hint: Join fetch loads related data in one query to boost speed [OK]
Common Mistakes:
Thinking join fetch deletes or updates data
Confusing join fetch with creating new tables
Assuming join fetch delays loading entities
2. Which of the following is the correct JPQL syntax to fetch a parent entity and its child entities using join fetch?
easy
A. SELECT p FROM Parent p JOIN FETCH p.children
B. SELECT p FROM Parent p JOIN p.children FETCH
C. SELECT p FROM Parent p FETCH JOIN p.children
D. SELECT p FROM Parent p LEFT JOIN p.children FETCH
Solution
Step 1: Recall correct JPQL join fetch syntax
The correct syntax places JOIN FETCH before the association path: JOIN FETCH p.children.
Step 2: Check each option
Only SELECT p FROM Parent p JOIN FETCH p.children matches the correct syntax. The others misuse the order of keywords or use incorrect join types.
Final Answer:
SELECT p FROM Parent p JOIN FETCH p.children -> Option A
Quick Check:
Join fetch syntax = JOIN FETCH association [OK]
Hint: Remember: 'JOIN FETCH' comes together before the association [OK]
Common Mistakes:
Swapping FETCH and JOIN keywords
Placing FETCH after the association path
Using FETCH without JOIN keyword
3. Given the following JPQL query:
SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id
What will happen when this query runs?
medium
A. It loads only the items without the Order
B. It loads the Order and all its items in one query, avoiding lazy loading
C. It throws a syntax error because JOIN FETCH cannot be used with WHERE
D. It loads only the Order, items are loaded lazily later
Solution
Step 1: Analyze the query structure
The query uses JOIN FETCH to eagerly load the items collection along with the Order entity filtered by id.
Step 2: Understand the effect of join fetch with WHERE
The WHERE clause filters the order, but the join fetch still loads the items eagerly in the same query.
Final Answer:
It loads the Order and all its items in one query, avoiding lazy loading -> Option B
Quick Check:
Join fetch + WHERE = eager load filtered data [OK]
Hint: Join fetch loads related data even with WHERE filters [OK]
Common Mistakes:
Thinking join fetch causes syntax errors with WHERE
Assuming items load lazily despite join fetch
Confusing join fetch with separate queries
4. Consider this JPQL query:
SELECT c FROM Customer c JOIN FETCH c.orders o WHERE o.status = 'PENDING'
What is the likely problem with this query?
medium
A. It may return duplicate Customer entities due to multiple matching orders
B. It will fail because JOIN FETCH cannot have an alias
C. It will not fetch orders eagerly because of the WHERE clause
D. It will only fetch orders with status other than 'PENDING'
Solution
Step 1: Understand join fetch with filtering on collection
Filtering on orders with WHERE o.status = 'PENDING' can cause multiple rows per customer if they have multiple pending orders.
Step 2: Recognize duplicate root entities issue
This leads to duplicate Customer entities in the result list unless distinct is used.
Final Answer:
It may return duplicate Customer entities due to multiple matching orders -> Option A
Quick Check:
Join fetch + filtered collection = possible duplicates [OK]
Hint: Filtering join fetch collections can cause duplicates [OK]
Common Mistakes:
Believing join fetch cannot have aliases
Thinking WHERE disables eager loading
Assuming only non-matching orders are fetched
5. You want to optimize loading a list of Author entities with their books and each book's publisher in one query. Which JPQL query correctly uses join fetch for this?
hard
A. SELECT a FROM Author a JOIN FETCH a.books, b.publisher
B. SELECT a FROM Author a JOIN a.books b JOIN FETCH b.publisher
C. SELECT a FROM Author a JOIN FETCH a.books JOIN b.publisher
D. SELECT a FROM Author a JOIN FETCH a.books b JOIN FETCH b.publisher
Solution
Step 1: Identify the need for nested join fetch
To load authors with books and each book's publisher eagerly, use join fetch on both associations.
Step 2: Check the syntax for multiple join fetches
SELECT a FROM Author a JOIN FETCH a.books b JOIN FETCH b.publisher correctly uses JOIN FETCH a.books b and then JOIN FETCH b.publisher to fetch nested associations.
Final Answer:
SELECT a FROM Author a JOIN FETCH a.books b JOIN FETCH b.publisher -> Option D