Java – spring data JPA – custom sorting in jparepository
I used spring data JPA and spring data rest and created a jparepository for my thing entity
@Repository public interface ThingRepository extends JpaRepository<Thing,Long> { @RestResource(path = "findByName",rel = "findByName") Page findByName(@Param("name") String name,Pageable page); }
I want to apply for ranking I want to sort the thing list according to the custom rating algorithm
List<Thing> sortByrating(List<Thing> things){ // custom logic return things; };
I want to use custom functions as much as possible to sort the results What is the best way to do this in spring JPA? How do I get my repository to use my functions to sort result sets?
Solution
Spring data provides basic sorting, as shown here You can also annotate the query with @ query and use order by, but I believe what you need is more complex sorting logic
If you are using java 8, you can use its function to sort the list. This article shows a good example. It needs more work, but it looks like what you are looking for Note that to convert from a stream to a list, you must include collect(Collectors.toList()); At the end of the stream
Example (from article):
employees.stream().sorted((Employee e1,Employee e2) -> e1.getHireDate() .compareTo(e2.getHireDate())).collect(Collectors.toList());
Editor: I didn't notice you were using paging I have a similar problem. I have to do something about the page content before returning the page object, so I finally created the extension of pageimpl < T > Class:
public class PageImplBean<T> extends PageImpl<T> { private static final long serialVersionUID = 1L; private int number; private int size; private int totalPages; private int numberOfElements; private long totalElements; private boolean prevIoUsPage; private boolean first; private boolean nextPage; private boolean last; private List<T> content; @JsonIgnore private Sort sort; public PageImplBean() { super(new ArrayList<T>()); } public PageImplBean(Page pagina){ super(new ArrayList<T>()); this.number = pagina.getNumber(); this.size = pagina.getSize(); this.totalPages = pagina.getTotalPages(); this.numberOfElements = pagina.getNumberOfElements(); this.totalElements = pagina.getTotalElements(); this.prevIoUsPage = pagina.hasPrevIoUs(); this.first = pagina.isFirst(); this.nextPage = pagina.hasNext(); this.last = pagina.isLast(); } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public int getTotalPages() { return totalPages; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public int getNumberOfElements() { return numberOfElements; } public void setNumberOfElements(int numberOfElements) { this.numberOfElements = numberOfElements; } public long getTotalElements() { return totalElements; } public void setTotalElements(long totalElements) { this.totalElements = totalElements; } public boolean isPrevIoUsPage() { return prevIoUsPage; } public void setPrevIoUsPage(boolean prevIoUsPage) { this.prevIoUsPage = prevIoUsPage; } public boolean isFirst() { return first; } public void setFirst(boolean first) { this.first = first; } public boolean isNextPage() { return nextPage; } public void setNextPage(boolean nextPage) { this.nextPage = nextPage; } public boolean isLast() { return last; } public void setLast(boolean last) { this.last = last; } public List<T> getContent() { return content; } public void setContent(List<T> content) { this.content = content; } public Sort getSort() { return sort; } public void setSort(Sort sort) { this.sort = sort; } public PageImpl<T> pageImpl() { return new PageImpl<T>(getContent(),new PageRequest(getNumber(),getSize(),getSort()),getTotalElements()); } }
In your case, the important thing is the setcontent method, which does not exist in the base class You can use it with your sorting method:
PageImplBean<Thing> page = //call your rest repository List<Thing> pageContent = page.getContent(); page.setContent(sortByrating(pageContent));