✅ Short Answer
Correct: In JPQL/HQL joins, you do not write ON tableA.key = tableB.foreignKey
like in SQL.
Instead, you navigate mapped entity relationships using Java object paths (e.g., o.customer
) → JPA knows how to join based on the entity mappings (@ManyToOne
, @OneToMany
, etc.).
🔎 Detailed Explanation
- In SQL, you manually join tables by specifying:
SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id
In JPQL/HQL, the ON
clause is not needed, because your JPA entity relationships already define how tables are related.
- JPA uses metadata from annotations like
@ManyToOne
or@OneToMany
to know which columns to join on. - You just join via object fields: javaCopyEdit
String jpql = "SELECT o FROM Order o JOIN o.customer c";
Here:
o.customer
navigates theOrder.customer
Java field.- JPA automatically generates the proper SQL join using the foreign key mapping defined in your entities.
🔹 Why you don’t need ON
✅ Mappings in entities define foreign key relationships once → no need to repeat in queries.
✅ Keeps JPQL/HQL concise and object-oriented.
✅ Reduces errors: the entity model guarantees the join path is correct.
🔹 Important Exception
- If you need complex joins without mapped associations, JPQL doesn’t support manual ON clauses like raw SQL.
- For such cases, you must:
- Use native SQL queries (
createNativeQuery()
), where you can write full SQL withON
. - Or map missing relationships in your entities.
- Use native SQL queries (
📌 Key Takeaways
✅ In JPQL/HQL, you never write ON key=foreignKey
— JPA uses mapped relationships to determine join conditions.
✅ You join via entity fields → e.g., o.customer
, not via table/column names.
✅ This makes JPQL simpler and less error-prone, leveraging your object model.