Discover how a simple annotation can save you hours of debugging messy database code!
Why @Query for custom JPQL in Spring Boot? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a database with many tables and you want to get specific data by writing complex queries manually in your code.
You write SQL queries as strings everywhere, mixing them with your Java code.
Writing raw SQL queries manually is error-prone and hard to maintain.
It mixes database logic with Java code, making your code messy and difficult to read.
Also, if the database changes, you have to find and update all those queries yourself.
The @Query annotation lets you write custom JPQL queries directly in your repository interfaces.
This keeps your queries organized, readable, and close to your Java code without mixing raw SQL strings everywhere.
It also integrates well with Spring Data, so you get type safety and easier maintenance.
String sql = "SELECT * FROM users WHERE age > 30"; // raw SQL in code List<User> users = entityManager.createNativeQuery(sql, User.class).getResultList();
@Query("SELECT u FROM User u WHERE u.age > 30")
List<User> findUsersOlderThan30();You can write clear, reusable, and maintainable database queries directly in your Java interfaces, making your data access layer clean and efficient.
In an online store app, you want to find all orders placed in the last month with a total price above a certain amount.
Using @Query, you write this complex query once in your repository and call it easily from your service code.
Manual SQL queries scattered in code are hard to maintain.
@Query centralizes and organizes custom JPQL queries.
This improves readability, safety, and ease of updates.
Practice
@Query annotation in Spring Data JPA?Solution
Step 1: Understand default query methods
Spring Data JPA provides default query methods like findById, but they are limited.Step 2: Role of @Query
@Query allows writing custom JPQL or SQL queries to handle complex or specific data retrieval needs.Final Answer:
To write custom JPQL or SQL queries when default methods are insufficient -> Option AQuick Check:
@Query purpose = custom queries [OK]
- Thinking @Query creates tables
- Confusing @Query with database config
- Assuming @Query defines entity relations
@Query in a Spring Data JPA repository interface?Solution
Step 1: Check JPQL syntax
JPQL uses entity names and fields, not table names or * syntax.Step 2: Parameter binding
Named parameters use :paramName and must be linked with @Param("paramName") in method.Final Answer:
@Query("SELECT u FROM User u WHERE u.name = :name") List<User> findByName(@Param("name") String name); -> Option AQuick Check:
JPQL + named param + @Param = correct syntax [OK]
- Using SQL syntax (*) instead of JPQL
- Missing @Param annotation for named parameters
- Using positional parameters incorrectly
@Query("SELECT u FROM User u WHERE u.age > :minAge")
List<User> findUsersOlderThan(@Param("minAge") int minAge);What will be the result of calling
findUsersOlderThan(30)?Solution
Step 1: Analyze the JPQL query
The query selects users where age is greater than the parameter minAge.Step 2: Understand method call
Calling findUsersOlderThan(30) sets minAge to 30, so users older than 30 are returned.Final Answer:
A list of User entities with age greater than 30 -> Option CQuick Check:
minAge=30, query > minAge = users older than 30 [OK]
- Confusing > with >= or =
- Assuming parameter is ignored
- Expecting users younger than 30
@Query("SELECT u FROM User u WHERE u.email = :email")
List<User> findByEmail(String email);Solution
Step 1: Check parameter binding
The query uses a named parameter :email, so the method parameter must have @Param("email") annotation.Step 2: Validate other parts
Entity name User is correct, return type List<User> is valid, and JPQL syntax is correct.Final Answer:
Missing @Param annotation for the email parameter -> Option BQuick Check:
Named param requires @Param annotation [OK]
- Omitting @Param causes runtime errors
- Confusing JPQL with native SQL
- Assuming return type must be single entity
@Query to find all users whose name contains a given substring (case insensitive). Which of the following method definitions correctly achieves this?Solution
Step 1: Understand case insensitive search
Use LOWER() on both field and parameter to ignore case.Step 2: Use LIKE with wildcards
Concatenate '%' before and after parameter to find substring matches.Step 3: Check parameter binding
Named parameter :namePart is linked with @Param("namePart") correctly.Final Answer:
@Query("SELECT u FROM User u WHERE LOWER(u.name) LIKE LOWER(CONCAT('%', :namePart, '%'))") List<User> findByNameContainsIgnoreCase(@Param("namePart") String namePart); -> Option DQuick Check:
LOWER + LIKE + CONCAT + @Param = correct case-insensitive contains [OK]
- Using LIKE with parameter inside quotes disables binding
- Not using LOWER() for case insensitivity
- Using = instead of LIKE for substring search
