Ответ
JPA Specifications — это паттерн из Spring Data JPA, который позволяет динамически и типобезопасно строить запросы с использованием JPA Criteria API. Это решение для сложной, составной фильтрации, когда условия запроса неизвестны на этапе компиляции.
Зачем это нужно? Чтобы избежать длинных цепочек if с проверками параметров и конкатенацией строк JPQL или использования @Query с SpEL.
Пример реализации:
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.*;
public class UserSpecifications {
// Спецификация для поиска по имени
public static Specification<User> hasName(String name) {
return (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) ->
cb.equal(root.get("name"), name);
}
// Спецификация для поиска пользователей старше указанного возраста
public static Specification<User> isOlderThan(int age) {
return (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) ->
cb.greaterThan(root.get("age"), age);
}
}
// Использование в сервисе:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAdultsByName(String name) {
// Комбинирование спецификаций
Specification<User> spec = Specification
.where(UserSpecifications.hasName(name))
.and(UserSpecifications.isOlderThan(17));
return userRepository.findAll(spec);
}
}
Преимущества:
- Типобезопасность и реюзабельность: Условия — это переиспользуемые Java-методы.
- Чистота кода: Логика запроса инкапсулирована, сервисный слой остается чистым.
- Гибкая композиция: Условия легко комбинируются с помощью
and(),or(),not(). - Поддержка пагинации и сортировки: Работает совместно с
PageableиSort.