Peter Penzov
Peter Penzov

Reputation: 1658

Sort order in search functionality

I use this code to get DB rows using JPA and Spring:

return transactionService.findAll(page, size)


        public Page<PaymentTransactions> findAll(int page, int size) {
        return dao.findAll(PageRequest.of(page,size, new Sort(Sort.Direction.DESC, "createdAt")));
        }

I would like to implement the same sorting for this code:

return transactionService.getAllBySpecification(specification, pageable)

      @Override
      public Page<PaymentTransactions> getAllBySpecification(final Specification<PaymentTransactions> specification, final Pageable pageable) {
          return dao.findAll(specification, pageable);
      }

Do you know how I can implement sorting direction by column using specification. Something like this:

return dao.findAll(specification, PageRequest.of(page,size, new Sort(Sort.Direction.DESC, "createdAt")));

Additionnal question:

Can I set Pagable object with sort direction? Something like this:

      @Override
      public Page<PaymentTransactions> getAllBySpecification(final Specification<PaymentTransactions> specification, final Pageable pageable) {
          return dao.findAll(specification, PageRequest.of(pageable, new Sort(Sort.Direction.DESC, "createdAt")));
      }

Upvotes: 4

Views: 332

Answers (2)

Marco R.
Marco R.

Reputation: 2720

You don't need anything else other than JpaSpecificationExecutor. Spring will use this interface to automatically create the:

Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)

method you seem to be looking for. So, it is unclear what the problem is, maybe you are importing the wrong classes? Or if you just want to generate PageRequest for the getAllBySpecification using page and size you can have something like this:

    public Page<Entity> getAllBySpecification(
            Specification<Entity> specification, 
            int page, int size) {
        
        return dao.findAll(specification, createMyPageRequest(page, size));
    }

    private PageRequest createMyPageRequest(int page, int size) {
        return PageRequest.of(page, size, new Sort(Sort.Direction.DESC, "createdAt"));
    }

In any event, if you need a complete compiling example of these APIs...

can you show me some code example please?

... here it is:

import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public class SortFunctionality {
    private Dao dao;
    
    public Page<Entity> findAll(int page, int size) {
        return dao.findAll(createMyPageRequest(page, size));
    }

    public Page<Entity> getAllBySpecification(
            Specification<Entity> specification, 
            int page, int size) {
        
        return dao.findAll(specification, createMyPageRequest(page, size));
    }
    
    public Page<Entity> getAllBySpecification(
            Specification<Entity> specification, 
            Pageable pageable) {
        
        PageRequest pageRequest = createMyPageRequest(
                pageable.getPageNumber(), 
                pageable.getPageSize());
        
        return dao.findAll(specification, pageRequest);
    }   

    private PageRequest createMyPageRequest(int page, int size) {
        return PageRequest.of(page, size, new Sort(Sort.Direction.DESC, "createdAt"));
    }

    static interface Dao extends 
        JpaRepository<Entity, Integer>, JpaSpecificationExecutor<Entity> {}
    
    static class Entity {}
}

Additional Question's Edit:

Yes you can achieve this by extracting the pageNumber and the pageSize from the Pageable argument and using them to create your custom PageRequest (PageRequest with hardcoded sorting criteria) with the createMyPageRequest utility that I included in the demo code. Finally, you can use that PageRequest to invoke the findAll method as usual:

    public Page<Entity> getAllBySpecification(
            Specification<Entity> specification, 
            Pageable pageable) {
        
        PageRequest pageRequest = createMyPageRequest(
                pageable.getPageNumber(), 
                pageable.getPageSize());
        
        return dao.findAll(specification, pageRequest);
    }   

I updated the previous full demo to reflect this new addition as well. Also it is a little bit refactored, so if you paste this new method over a copy previous version of the demo it will have errors.

Complete code on GitHub

Hope this helps.

Upvotes: 3

Borislav Markov
Borislav Markov

Reputation: 1725

You can use only naming convention and let Spring generate implementation for you. You have to use Spring data JPA repositories. You can follow the examples given and refactor your logic accordingly.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.special-parameters

It also an take parameter Pageable. Please look at the examples:

List<Person> findByLastnameOrderByFirstnameDesc(String lastname);

And this one:

Page<User> findByLastname(String lastname, Pageable pageable);

Pageable and Slice are described in 4.4.4 Special parameter handling.

Upvotes: 0

Related Questions