JPQL vs HQL vs Native SQL

Author Avatar
Learn Here Fun Pedia
5 min read •

1. JPQL

Now let's move to queries. JPQL stands for Java Persistence Query Language. It operates on Entities and Entity attributes, not directly on database tables or columns.

Suppose you have the following entity:

@Entity
class Employee {
    private Long id;
    private String name;
    private double salary;
}

A JPQL query looks like this:

SELECT e
FROM Employee e
WHERE e.salary > 50000

Notice that Employee is the Java entity name (not the database table name like employee_table), and e.salary is the Java entity field (not the database column like salary_column).

2. JPQL vs SQL

The mental difference is crucial for mastering Hibernate:

SQL
 ↓
Operates on Tables + Columns

JPQL
 ↓
Operates on Entities + Fields

SQL: SELECT * FROM employee WHERE salary > 50000;
JPQL: SELECT e FROM Employee e WHERE e.salary > 50000

3. HQL

HQL stands for Hibernate Query Language. It is Hibernate's object-oriented query language.

FROM Employee e
WHERE e.salary > 50000

Hibernate's HQL is very similar to JPQL. The practical distinction for interviews is:

  • JPQL: The standardized query language defined by the JPA specification.
  • HQL: Hibernate's specific query language, which supports JPQL but extends it with Hibernate-specific capabilities.

4. Native SQL

Sometimes you need actual database SQL to leverage complex, vendor-specific database features. With Spring Data JPA, you can execute Native SQL by using the nativeQuery = true flag:

@Query(
    value = "SELECT * FROM employee WHERE salary > :salary",
    nativeQuery = true
)
List<Employee> findEmployees(@Param("salary") double salary);

Here, nativeQuery = true means: Treat the query as pure database SQL rather than JPQL.

5. JPQL vs HQL vs Native SQL

Feature JPQL HQL Native SQL
Standard JPA Hibernate Database
Operates on Entities Entities Tables
Uses Entity fields Entity fields DB columns
Portability High (Cross-ORM) Hibernate-specific Lower (DB-specific)
Features Limited to JPA standard Full Hibernate features Full Database features
Typical use Normal application queries Hibernate-specific queries Complex/vendor-specific SQL

6. Query Parameters

Never build queries by concatenating user input. This is a severe anti-pattern:

// BAD - Vulnerable to SQL Injection
String query = "SELECT e FROM Employee e WHERE e.name = '" + name + "'";

This can create security and correctness problems, including SQL injection risks. Instead, always use parameters.

// GOOD
SELECT e FROM Employee e WHERE e.name = :name
query.setParameter("name", name);

7. Named Parameters

In Spring Data JPA, named parameters are heavily used and highly readable. A named parameter is prefixed with a colon (:).

@Query("""
    SELECT e
    FROM Employee e
    WHERE e.salary > :salary
""")
List<Employee> findEmployees(@Param("salary") double salary);

Think of the flow as: Query → :salary (placeholder) → setParameter() → actual value.

8. Positional Parameters

You can also use positional parameters, which use a question mark followed by a number:

SELECT e FROM Employee e WHERE e.salary > ?1
query.setParameter(1, 50000);

However, named parameters are generally preferred because they are easier to read, maintain, and are less prone to breaking if the query structure changes.

T3 Interview Summary

If the interviewer asks: "What is the difference between JPQL and Native SQL?"

"JPQL operates on Java Entity classes and their fields, making it database-agnostic and highly portable across different SQL dialects. Native SQL operates directly on database tables and columns, which ties your code to a specific database vendor but allows you to utilize complex, database-specific features (like window functions or specific JSON operators) that JPQL does not support."

Important Interview Questions (FAQs)

Q1: Why should I use parameterized queries instead of string concatenation?

String concatenation leaves your application highly vulnerable to SQL Injection attacks, where malicious users can manipulate the query logic. Parameterized queries (using named or positional parameters) ensure that user input is treated strictly as data, not executable code.

Q2: How do you tell Spring Data JPA that a query is Native SQL?

You use the @Query annotation and set the nativeQuery attribute to true (e.g., @Query(value = "SELECT * FROM my_table", nativeQuery = true)). This tells the framework to bypass the JPQL parser and send the string directly to the database.

Q3: Is HQL portable to other JPA providers like EclipseLink?

No. While basic JPQL syntax works in HQL, HQL includes Hibernate-specific extensions that are not part of the JPA standard. If you use those extensions, your code will be tied to Hibernate and will not easily port to EclipseLink or other JPA providers.

Comments (0)