JPQL vs SQL in JPA
Fast recall
Quick revision
Core answer
Whether you grasp that JPQL operates on the object model (entities/fields) while SQL operates on the schema (tables/columns)
Writing table and column names in JPQL (SELECT * FROM users) instead of entity and field names (SELECT u FROM User u)
Mention database portability and JOIN FETCH for N+1, and when to switch to native queries
Interview-ready guide
Interview answer
A JPQL join follows a mapped relationship such as o.customer, while SQL joins the foreign-key columns directly. The provider resolves entity metadata, binds parameters, and renders dialect SQL. JOIN FETCH is a JPQL fetch-plan tool, not a rule that every association should be joined. A projection can select only the fields needed by a read endpoint.
JPQL vs SQL in JPA
Direct Answer
JPQL names entities and their mapped attributes; SQL names database tables, columns, and functions. The JPA provider translates JPQL into SQL for the configured dialect. JPQL is more portable for supported standard behavior, but database schemas, functions, null/collation rules, provider extensions, and generated plans still differ, so it is not a guarantee of database-independent behavior.
Code Example
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
// Join across a relationship
@Query("SELECT o FROM Order o JOIN o.user u WHERE u.email = :email")
List<Order> findByUserEmail(@Param("email") String email);
// Aggregate
@Query("SELECT COUNT(o) FROM Order o WHERE o.status = :status")
long countByStatus(@Param("status") OrderStatus status);
// JOIN FETCH solves N+1 by loading the collection in one query
@Query("SELECT o FROM Order o JOIN FETCH o.lineItems WHERE o.id = :id")
Optional<Order> findWithItems(@Param("id") Long id);
// Constructor expression → DTO projection
@Query("SELECT new com.example.dto.OrderSummary(o.id, o.total) FROM Order o")
List<OrderSummary> summaries();
}
Common Mistakes & Pitfalls
- Table names instead of entities —
FROM usersfails; it must beFROM User. - Column names instead of fields — use
u.email(Java field), notu.email_address(DB column). - Cross-join SQL style — write
JOIN u.orders o, notFROM User u, Order o WHERE .... - Forgetting JOIN FETCH — a plain JOIN still triggers N+1 when you access the relation later.
Check your understanding
Answer these without looking back at the article.
- When would you use native SQL over JPQL?
- How do you use @Query in Spring Data JPA?
- What is the Criteria API in JPA?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.