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));
