У меня есть объект Service с полем Jobs, у которого есть объект Job в отношении ManyToMany.
Фильтрация, сортировка и разбиение на страницы работают отлично, но единственной проблемой является сортировка по Джобсу.
Когда я отправляю запрос на /serviceslist?sort=jobs&sortDir=asc
, я получаю повторяющиеся результаты для каждой службы, к которой подключено несколько заданий.Если быть более точным, если у Службы 4 задания, то служба возвращается 4 раза и т. Д.
Я думаю, что мне следует использовать groupBy, но как мне реализовать groupBy в моей службе ниже?
Служба:
public Page<com.bitweb.syda.data.entity.service.Service> getServicesList(ServiceListRequest request, Pageable pageable) {
Specification<com.bitweb.syda.data.entity.service.Service> spec = where(null);
if (request.getSearch() != null) spec = spec.and(search(request.getSearch()));
if (request.getName() != null) spec = spec.and(name(request.getName()));
if (request.getJobs() != null) spec = spec.and(hasJobs(request.getJobs()));
if (request.getNeedsPatrol() != null) spec = spec.and(needsPatrol(request.getNeedsPatrol()));
return serviceRepository.findAll(spec, pageable);
}
Контроллер:
@RequestMapping(path = "/serviceslist", method = RequestMethod.GET)
public Page<ServiceResponse> getServicesList(
@RequestParam(defaultValue = "0") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String search,
@RequestParam(required = false) String name,
@RequestParam(required = false) String jobs,
@RequestParam(required = false) Boolean needsPatrol,
@RequestParam(defaultValue = "createTime") String sort,
@RequestParam(defaultValue = "asc") String sortDir
) {
ServiceListRequest request = new ServiceListRequest(search, name, jobs, needsPatrol);
Sort.Direction direction;
if (sortDir.equals("asc")) {
direction = Sort.Direction.ASC;
} else {
direction = Sort.Direction.DESC;
}
return serviceService.getServicesList(request, of(page, size, direction, sort))
.map(ServiceResponse::new);
}
Вот несколько примеров того, что я уже пробовал:
public Page<com.bitweb.syda.data.entity.service.Service> getServicesList(ServiceListRequest request, Pageable pageable) {
Specification<com.bitweb.syda.data.entity.service.Service> spec = (root, query, builder) -> {
//you can do any check here if you want with the join and check all the search parameters here if you want
//Join<Object, Object> jobs = root.join("jobs");
// also set query to get distinct values
query.distinct(true);
return null;
};
if (request.getSearch() != null) spec = spec.and(search(request.getSearch()));
if (request.getName() != null) spec = spec.and(name(request.getName()));
if (request.getJobs() != null) spec = spec.and(hasJobs(request.getJobs()));
if (request.getNeedsPatrol() != null) spec = spec.and(needsPatrol(request.getNeedsPatrol()));
return serviceRepository.findAll(spec, pageable);
}
После попытки все работает какожидается, но сортировка по заданиям дает мне эту ошибку:
PSQLException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
Position: 652
Я не очень хорошо разбираюсь в SQL и Criteria API и не знаю, что можно сделать, чтобы это исправить.
При использовании query.groupBy(root);
вместо отчетливого я получаю эту ошибку:
PSQLException: ERROR: column "job4_.id" must appear in the GROUP BY clause or be used in an aggregate function
Position: 780