Spring Data JPA — Custom Queries
Write custom JPA queries with @Query, derived methods, Specifications, and native SQL for complex lookups.
import org.springframework.data.jpa.repository.*;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import java.time.LocalDate;
import java.util.*;
public interface UserRepository extends JpaRepository<User, Long>,
JpaSpecificationExecutor<User> {
// Derived query methods
Optional<User> findByEmail(String email);
List<User> findByNameContainingIgnoreCase(String name);
List<User> findByCreatedAtAfter(LocalDate date);
boolean existsByEmail(String email);
long countByStatus(String status);
// JPQL query
@Query("SELECT u FROM User u WHERE u.age BETWEEN :min AND :max ORDER BY u.name")
List<User> findByAgeRange(int min, int max);
// JPQL with join fetch (avoid N+1)
@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders WHERE u.id = :id")
Optional<User> findByIdWithOrders(Long id);
// Native SQL
@Query(value = "SELECT * FROM users WHERE email LIKE %:domain", nativeQuery = true)
List<User> findByEmailDomain(String domain);
// Pagination
Page<User> findByStatus(String status, Pageable pageable);
// Modifying query
@Modifying
@Query("UPDATE User u SET u.status = :status WHERE u.lastLogin < :date")
int deactivateInactiveUsers(String status, LocalDate date);
}
// Specification for dynamic queries
class UserSpecs {
static Specification<User> hasName(String name) {
return (root, query, cb) ->
name == null ? null : cb.like(cb.lower(root.get("name")), "%" + name.toLowerCase() + "%");
}
static Specification<User> hasStatus(String status) {
return (root, query, cb) ->
status == null ? null : cb.equal(root.get("status"), status);
}
static Specification<User> ageGreaterThan(int age) {
return (root, query, cb) -> cb.greaterThan(root.get("age"), age);
}
}
// Usage: repo.findAll(hasName("alice").and(hasStatus("active")), pageable);Sponsored
Supabase
Use Cases
- Complex database queries in Spring applications
- Dynamic filtering with JPA Specifications
- Avoiding N+1 query problems with fetch joins
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
JPA Entity Mapping with Relationships
Map entities with JPA annotations: OneToMany, ManyToOne, ManyToMany with fetch strategies and cascading.
Best for: Database schema design with JPA entities
Spring Data — Pagination and Sorting
Implement pagination with Spring Data JPA: Pageable, Sort, Slice, and custom page responses.
Best for: Paginated API responses for large datasets
Spring Data JPA with Kotlin
Build data layers with Spring Data JPA in Kotlin: entities, repositories, queries, and pagination.
Best for: CRUD operations with Spring Data
Spring Data with Kotlin Repository Patterns
Use Spring Data JPA with Kotlin: entity mapping, custom queries, projections, and specifications.
Best for: Database access with Spring Data JPA in Kotlin