Логотип Workflow

Article

Updated at:

Jpql

Stage 6 - JPQL: Querying Entities Instead of Tables

JPQL queries the entity model, while SQL queries the database schema. It looks similar to SQL, but it operates on entity classes and entity fields, not directly on table names and column names. SQL says select * from users; JPQL says SELECT u FROM User u. Hibernate translates JPQL into SQL for the target database.

JPQL compared to SQL

JPQL syntax

The basic query selects from an entity:

@Query("SELECT u FROM User u")
List<User> findAllUsers();

User is the entity class name, and u is an alias. Conditions use entity field names:

@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> findByEmail(@Param("email") String email);

JPQL supports WHERE, ORDER BY, GROUP BY, aggregate functions, and joins through entity relationships. A join follows object references, not raw foreign key columns:

@Query("SELECT o FROM Order o JOIN o.user u WHERE u.email = :email")
List<Order> findOrdersByUserEmail(@Param("email") String email);

Parameters

Named parameters use :name and are usually clearer than positional parameters. Positional parameters use ?1, ?2, and so on. Named parameters survive refactoring better because their meaning is visible in the query.

Query needBetter JPQL styleWhy this explains the intent
Filter by one clear business valueWHERE u.email = :emailThe parameter name documents that the value is an email, not just the first argument.
Filter by several valuesWHERE p.price BETWEEN :min AND :maxNamed parameters prevent confusion when two values have the same Java type.
Join through a relationshipJOIN o.user uJPQL follows the entity relation instead of manually writing orders.user_id = users.id.
Return a list screenSELECT new ...ProductSummary(...)DTO projection loads only the fields that the response actually needs.

DTO projection

Sometimes an API needs only a few fields. Loading full entities can be wasteful, especially when relationships are involved. JPQL can create DTO projections:

@Query("""
    SELECT new com.example.UserSummary(u.id, u.email, u.name)
    FROM User u
    WHERE u.active = true
    ORDER BY u.name
""")
List<UserSummary> findActiveUserSummaries();

DTO projection is useful for read-only screens, list endpoints, and reporting. It reduces loaded data and avoids accidental lazy loading. The tradeoff is that the DTO constructor and query must match.

JPQL vs derived queries

Spring Data can create queries from method names, such as findByEmail or findByNameContainingIgnoreCase. This is excellent for simple conditions. JPQL is better when the query needs joins, grouping, custom sorting logic, projections, or a condition that would make the method name unreadable.

Practice

Add queries for searching users by email, filtering products by price range and availability, and sorting products by name. Then add a DTO projection that returns only product id, name, and price. Compare generated SQL with SQL logging. The goal is not to memorize JPQL syntax, but to understand that JPQL describes operations on the entity model.

Understanding checklist

  • I can explain how JPQL differs from SQL.
  • I know that JPQL uses entity names and field names.
  • I can use @Query with named parameters.
  • I understand when DTO projection is useful.
  • I can choose between derived query methods and JPQL.

Please login to pass quizzes.

Practice

Interactive practice

Complete tasks and check your answer instantly.