Core idea:
When you have a bidirectional lazy @OneToMany association (e.g., Author → Book), you often want to fetch all left-side entities (all Authors) and their associated collections (Books) in a single query — without losing left-side rows that have no children.
JOIN FETCHbecomes an INNER JOIN, so it excludes left-side entities that have no associated children.- Example: Authors with zero books would be missing.
LEFT JOINkeeps all left-side rows, but does not fetch collections in the same SELECT when using JPA/Hibernate.
This combines the benefits of both:
- Keeps all left-side entities (like
LEFT JOIN) - Fetches lazy collections in the same query (like
JOIN FETCH)
@Query("SELECT a FROM Author a LEFT JOIN FETCH a.books")
List<Author> fetchAuthorWithBooks();Generated SQL includes:
LEFT JOIN book b1_0 ON a1_0.id=b1_0.author_id
@Query("SELECT b FROM Book b LEFT JOIN FETCH b.author")
List<Book> fetchBookWithAuthor();Also produces a LEFT OUTER JOIN.
- You can fetch all Authors, including those without Books, with their collections initialized.
- Same applies in reverse for Books → Author.