Spring Boot JPA Specifications (Specification<T>)
~1 min read
·
Spring Boot
Spring Data JPA Specifications allow you to create dynamic queries with filtering conditions in a flexible way.
Why Use Specification<T> ? Build dynamic queries based on user input. Avoid writing multiple static queries. Combine multiple conditions easily (AND , OR ). Supports pagination & sorting .
Adding Dependency Ensure you have Spring Data JPA dependency and lombok in your pom.xml :
org.springframework.boot
spring-boot-starter-data-jpa
org.projectlombok
lombok
1.18.34
provided
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Example Entity Class Let's assume we have a User entity with fields: id , name , email and age
user.java
import jakarta.persistence.*;
import lombok.*;
@Entity
@Table(name = "user")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private int age;
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Table name : user
id
name
email
age
1
John
john@gmail.com
25
2
Mike
mike@gmail.com
35
3
Watson
watson@gmail.com
40
4
Kenny
kenny@gmail.com
45
Create Specification
UserService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// ✅ Get Users with Dynamic Filters
public List searchUsers(String name, Integer age, String email) {
Specification spec = Specification.where(UserSpecification.hasName(name))
.or(UserSpecification.hasAgeGreaterThan(age))
.or(UserSpecification.hasEmail(email));
return userRepository.findAll(spec);
}
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Each method returns a Specification<User> that dynamically applies a filtering condition.
Create Repository Using JpaSpecificationExecutor Spring Data JPA provides JpaSpecificationExecutor for dynamic queries. JpaSpecificationExecutor<User> allows dynamic querying with Specification<User> .
UserRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface UserRepository extends JpaRepository, JpaSpecificationExecutor {
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Create Services
UserService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// ✅ Get Users with Dynamic Filters
public List searchUsers(String name, Integer age, String email) {
Specification spec = Specification.where(UserSpecification.hasName(name))
.or(UserSpecification.hasAgeGreaterThan(age))
.or(UserSpecification.hasEmail(email));
return userRepository.findAll(spec);
}
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Create Controllers
UserController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
// ✅ Search Users with Filters
@GetMapping("/search")
public ResponseEntity> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age,
@RequestParam(required = false) String email) {
return ResponseEntity.ok(userService.searchUsers(name, age, email));
}
}
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Testing the REST API with Postman: Once the application is running, test the endpoints:
Get User like name GET:http://localhost:8080/users/search?name=John
SELECT * FROM users WHERE name LIKE '%John%';
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Get User by age greaterThanOrEqualTo GET:http://localhost:8080/users/search?age=40
SELECT * FROM users WHERE age >= 25;
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">
Get User by like name or greaterThanOrEqualTo age GET:http://localhost:8080/users/search?name=John&age=40
SELECT * FROM users WHERE name LIKE '%John%' OR age >= 25;
show = true, 3000)" class="absolute top-[10px] right-[10px] inline-flex items-center justify-center gap-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-smooth h-9 rounded-md px-3 cursor-pointer bg-white/80 border border-border">