4. JPQL and Native Query Questions
T
Tuan Nguyen

4. JPQL and Native Query Questions

This section focuses on how JPA and Spring Data JPA execute database queries using JPQL, native SQL, dynamic query building, and repository query mechanisms for complex data access operations

1. What is JPQL?

JPQL stands for Java Persistence Query Language.

JPQL is a query language defined by JPA for querying entities instead of querying database tables directly.

Unlike SQL, JPQL works with:

  • Entity classes

  • Entity fields

  • Object relationships

instead of:

  • Database tables

  • Database columns

Example entity:

@Entity
public class User {

    @Id
    private Long id;

    private String name;
}

JPQL example:

SELECT u FROM User u

This means:

  • User → entity class

  • u → entity alias

Hibernate internally converts JPQL into database-specific SQL.

Possible generated SQL:

SELECT * FROM users;

JPQL is database-independent because developers work with entities instead of vendor-specific SQL syntax.

This is one of the major advantages of ORM frameworks.


2. How is JPQL different from SQL?

JPQL and SQL look similar syntactically, but they operate at different abstraction levels.


SQL

SQL works directly with database structures.

Example:

SELECT * FROM users;

Uses:

  • Table names

  • Column names

  • Database schema

SQL is database-oriented.


JPQL

JPQL works with entity models.

Example:

SELECT u FROM User u

Uses:

  • Entity names

  • Entity fields

  • Object relationships

JPQL is object-oriented.


Key difference:

JPQL

SQL

Uses entities

Uses tables

Uses fields

Uses columns

Database-independent

Database-specific

ORM-oriented

Database-oriented

Works with object model

Works with relational model

Hibernate converts JPQL into SQL internally.


3. Does JPQL use table names or entity names?

JPQL uses entity names.

Example:

@Entity
public class User {
}

JPQL:

SELECT u FROM User u

NOT:

SELECT * FROM users

Even if the table is:

users

JPQL still uses:

User

because JPQL operates on entity metadata, not directly on database tables.


4. Does JPQL use column names or field names?

JPQL uses entity field names.

Example:

private String email;

JPQL:

SELECT u.email FROM User u

NOT database column names.

Even if database column is:

user_email

JPQL still uses:

email

because JPQL interacts with the Java object model.


5. What is a native query?

A native query is a real SQL query written directly for the database.

Example:

@Query(value = "SELECT * FROM users", nativeQuery = true)
List<User> findAllUsers();

Unlike JPQL:

  • Native query uses actual SQL syntax

  • Uses table names

  • Uses column names

  • Database executes query directly

Hibernate does not translate the query.


6. When should you use native SQL?

Native SQL is usually used when JPQL is insufficient.

Common cases:

Situation

Reason

Complex joins

JPQL limitations

Database-specific functions

Vendor features

Performance optimization

Fine SQL control

Window functions

Advanced SQL

Recursive queries

JPQL cannot handle well

Stored procedures

Database integration

Example:

ROW_NUMBER()
WITH RECURSIVE
JSONB operators

These are database-specific features often unavailable in JPQL.


7. How do you write a JPQL query in Spring Data JPA?

Using @Query.

Example:

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

This is JPQL because:

  • User is entity name

  • email is entity field

Hibernate converts it internally into SQL.


8. How do you write a native query in Spring Data JPA?

Set:

nativeQuery = true

Example:

@Query(
    value = "SELECT * FROM users WHERE email = :email",
    nativeQuery = true
)
User findByEmail(@Param("email") String email);

This query executes directly in database.


9. What is the difference between positional parameters and named parameters?

JPQL supports two parameter styles.


Positional Parameters

Uses index positions.

Example:

@Query("SELECT u FROM User u WHERE u.email = ?1")
User find(String email);

?1 means first parameter.

Disadvantages:

  • Harder to read

  • Easier to make mistakes


Named Parameters

Uses parameter names.

Example:

@Query("SELECT u FROM User u WHERE u.email = :email")
User find(@Param("email") String email);

Advantages:

  • More readable

  • Easier maintenance

  • Better for complex queries

Named parameters are preferred in enterprise applications.


10. What is @Param?

@Param binds method parameters to named query parameters.

Example:

@Query("SELECT u FROM User u WHERE u.email = :email")
User find(@Param("email") String email);

Binding:

Query Parameter

Method Parameter

:email

String email

Without @Param, Spring may not know which method parameter maps to which query parameter.


11. Can JPQL perform joins?

Yes.

JPQL supports joins between entity relationships.

Example:

SELECT o
FROM Order o
JOIN o.user u
WHERE u.name = :name

Important detail:

JPQL joins use entity relationships, not foreign key columns directly.

Example:

@ManyToOne
private User user;

JPQL navigates through object relationships.


12. Can JPQL select DTOs directly?

Yes.

JPQL supports DTO projection.

Example:

SELECT new com.example.UserDto(u.name, u.email)
FROM User u

Instead of loading full entities, Hibernate creates DTO objects directly.

This improves:

  • Performance

  • Memory usage

  • API response optimization

because unnecessary entity loading is avoided.


13. What is constructor expression in JPQL?

Constructor expression allows JPQL to instantiate DTO objects directly.

Syntax:

SELECT new package.ClassName(...)

Example:

SELECT new com.example.UserDto(u.name, u.email)
FROM User u

Hibernate calls DTO constructor internally.

Equivalent logic:

new UserDto(name, email)

for every query row.


14. Example: select new com.example.UserDto(u.name, u.email) from User u — what does it do?

This query creates DTO objects directly from query results.

Instead of returning:

User entity

it returns:

UserDto

Hibernate extracts:

  • u.name

  • u.email

then calls:

new UserDto(name, email)

Benefits:

  • Smaller response payload

  • Faster query execution

  • Avoids unnecessary entity loading

  • Reduces memory usage

Very common in APIs and reporting systems.


15. Can JPQL use database-specific functions?

Limited support exists.

JPQL itself is database-independent, so vendor-specific features are restricted.

Hibernate provides some support through:

FUNCTION(...)

Example:

SELECT FUNCTION('DATE_FORMAT', u.createdAt, '%Y')
FROM User u

But portability becomes weaker.

For heavily database-specific logic, native SQL is usually preferred.


16. What are the disadvantages of native queries?

Native queries reduce portability and ORM abstraction benefits.

Main disadvantages:

Problem

Explanation

Database dependency

SQL may not work across databases

Harder maintenance

SQL tightly coupled to schema

Less portability

Vendor-specific syntax

ORM abstraction reduced

More database-oriented code

Manual mapping complexity

DTO/entity mapping harder

Example:

A PostgreSQL query may fail completely in Oracle or MySQL.


17. What are the advantages of native queries?

Native queries provide maximum SQL control.

Advantages:

Advantage

Explanation

Full SQL power

Access all database features

Better optimization

Fine-tuned SQL

Complex analytics

Window functions, CTEs

Database-specific features

Vendor capabilities

Potential performance gains

Optimized execution plans

Enterprise systems often mix:

  • JPQL for standard operations

  • Native SQL for performance-critical queries


18. What is dynamic query building?

Dynamic query building means constructing queries programmatically at runtime.

Useful when filters are optional.

Example search API:

name optional
age optional
status optional
date optional

Instead of writing many repository methods:

findByNameAndAgeAndStatus...

queries are built dynamically depending on provided filters.

Dynamic query building is common in:

  • Search systems

  • Reporting

  • Admin dashboards

  • Complex filtering APIs


19. What is Criteria API?

Criteria API is a JPA API for building type-safe dynamic queries programmatically.

Example:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);

query.select(root)
     .where(cb.equal(root.get("name"), "John"));

Advantages:

  • Dynamic query generation

  • Type safety

  • Better for optional filters

Disadvantages:

  • Verbose

  • Harder readability

  • Complex syntax

Many developers consider Criteria API difficult to read.


20. What is Specification in Spring Data JPA?

Specification is Spring Data JPA’s abstraction built on top of Criteria API.

It simplifies dynamic query creation.

Example:

public class UserSpecification {

    public static Specification<User> hasName(String name) {
        return (root, query, cb) ->
            cb.equal(root.get("name"), name);
    }
}

Specifications can be combined dynamically:

spec1.and(spec2)
spec1.or(spec2)

This is very useful for:

  • Dynamic filtering

  • Search APIs

  • Enterprise query systems

  • Reusable query logic

Specification is widely used in large Spring Boot applications because it is cleaner than raw Criteria API while still supporting dynamic query construction.

Comments