Java.Hibernate.Medium.What’s the difference between fetch joins and normal joins in HQL?

Short Answer

  • A normal join (JOIN, LEFT JOIN) combines tables/entities for filtering or constraints, but does not fetch related entities into your object graph.
  • A fetch join (JOIN FETCH) loads the associated entities eagerly along with the parent in a single query, populating their fields immediately — crucial to avoid the N+1 problem.

🔎 Detailed Explanation

🔹 Normal Joins

  • Used when you want to filter or restrict results based on related entity data.
  • Does not load associated entities into memory → they remain lazily loaded if marked as lazy.
  • Typically returns only the parent entity or fields selected.

Example:

String hql = "SELECT o FROM Order o JOIN o.customer c WHERE c.status = :status";
List<Order> orders = em.createQuery(hql, Order.class)
                       .setParameter("status", "ACTIVE")
                       .getResultList();

✅ This filters orders by customer status.
❌ But o.customer remains uninitialized (lazy) → accessing order.getCustomer() later can still trigger an extra SQL query.

🔹 Fetch Joins

  • Uses JOIN FETCH to tell Hibernate/JPA to load the related entities right away.
  • Fetched entities are fully initialized and attached to the parent.
  • Avoids lazy-loading and solves the N+1 problem.

Example:

String hql = "SELECT o FROM Order o JOIN FETCH o.customer c WHERE c.status = :status";
List<Order> orders = em.createQuery(hql, Order.class)
                       .setParameter("status", "ACTIVE")
                       .getResultList();

✅ Here, each Order comes with its Customer already loaded, even if customer was mapped as lazy.

📊 Quick Comparison Table

FeatureNormal JOINJOIN FETCH
PurposeFiltering/constraintsFetching associations eagerly
Loads child entity?❌ No✅ Yes
Solves N+1?❌ No✅ Yes
ReturnsParent or selected fieldsParent with initialized associations

🔹 Important Notes
✅ Both joins use entity relationships → no SQL ON clauses.
❗ Fetch joins cannot be used in subqueries → only top-level JPQL/HQL.
❗ Fetch joins on collections can cause duplicate parent rows → careful with pagination.

This entry was posted in Без рубрики. Bookmark the permalink.

Leave a Reply

Your email address will not be published.