Что такое JPA Specifications в Spring Data JPA?

«Что такое JPA Specifications в Spring Data JPA?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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.