woytech
woytech

Reputation: 771

Can I combine a @Query definition with a Specification in a Spring Data JPA repository method?

Is it possible to use both @Query annotation and specification in one repository method? For example I'd like to have a method like this:

@Query(value="SELECT e from EMPLOYEE where firstName <> ?1")
public Page<Employee> findEmployeeBySomethigFancy(String firstName, Pageable pageable, Specification<Employee> emp);

Is it possible or should I build the whole query as a Predicate and remove the @Query annotation?

Upvotes: 63

Views: 55558

Answers (2)

I did this workaround in order to have a response other than the entity type using the specification I have, maybe it can help you to resolve your needs without @Query:

public ImovelFilterResponseDTO getImovelsFilterByCriteria(Specification<Imovel> specification) {
    ImovelFilterResponseDTO imovelFilterResponseDTO = new ImovelFilterResponseDTO();
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<BigDecimal> query = builder.createQuery(BigDecimal.class);
    Root<Imovel> root = query.from(Imovel.class);
    Predicate predicate = specification.toPredicate(root, query, builder);
    if (predicate != null) {
        query.where(predicate);
    }
    BigDecimal areaHectaresMax =  entityManager.createQuery(query.select(builder.max(root.<BigDecimal>get("areaHectares")))).getSingleResult();
    imovelFilterResponseDTO.setFilterMaxArea(areaHectaresMax);
    return imovelFilterResponseDTO;
}

Upvotes: 1

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153780

First thing, you should read this Spring blog post.

Second, according to the JpaSpecificationExecutor interface, that your repositories should implement, the following method take a Specification argument:

  • count(Specification<T> spec)
  • List<T> findAll(Specification<T> spec)
  • Page<T> findAll(Specification<T> spec, Pageable pageable)
  • List<T> findAll(Specification<T> spec, Sort sort)
  • T findOne(Specification<T> spec)

So, you can't mix a @Query definition with a Specification.

However, since you can express the firstName <> ?1 condition using a Specification and because you combine as many specifications as you want, you can rewrite the whole @Query using Specification(s) only.

Upvotes: 68

Related Questions