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)
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.
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.
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)