In JPA, you join tables by navigating entity relationships in JPQL/HQL queries, using JOIN
, LEFT JOIN
, or JOIN FETCH
— just like in Hibernate HQL — since JPA uses JPQL as its standard query language.
🔎 Detailed Explanation
JPA Joins use mapped entity associations, not raw SQL joins on tables.
You specify joins on entity fields annotated with relationships like @ManyToOne
, @OneToMany
, etc.
🔹 Basic Inner Join Example
Given entities:
@Entity
public class Order {
@ManyToOne
private Customer customer;
}
JPQL join:
String jpql = "SELECT o FROM Order o JOIN o.customer c WHERE c.status = :status";
List<Order> orders = entityManager.createQuery(jpql, Order.class)
.setParameter("status", "ACTIVE")
.getResultList();
Here, o.customer
navigates the Order
→Customer
relationship.
🔹 Left Outer Join Example
Loads all orders even if they don’t have a customer:
String jpql = "SELECT o FROM Order o LEFT JOIN o.customer c";
List<Order> orders = entityManager.createQuery(jpql, Order.class)
.getResultList();
🔹 Fetch Join Example
Eagerly loads customers along with orders in a single query (avoiding N+1 problem):
🔹 Fetch Join Example
Eagerly loads customers along with orders in a single query (avoiding N+1 problem):
🔹 Join with Multiple Levels
If you have deeper relationships, you can join multiple associations:
String jpql = "SELECT o FROM Order o " +
"JOIN o.customer c " +
"JOIN c.address a " +
"WHERE a.city = :city";
List<Order> orders = entityManager.createQuery(jpql, Order.class)
.setParameter("city", "New York")
.getResultList();