У меня есть класс с множеством полей, отношением «многие к одному» и «многие ко многим», и мне нужно добавить динамические фильтры по некоторым столбцам (из этого класса и по полям из подключенного класса) и добавить сортировку поа также эти поля.
У меня проблема с фильтрацией и сортировкой по полю "многие ко многим"
@Entity
class EntityA {
...
@ManyToMany
@JoinTable (
name = "EntityA_EntityB",
joinColumns = { @JoinColumn(name = "EntityB") },
inverseJoinColumns = { @JoinColumn(name = "entityb_id") }
)
private List<EntityB> bEntities;
...
}
И у меня есть спецификация для фильтрации EntityA по EntityB.name (я установил критерииQuery.distinct (true) для предотвращения дубликатов, которые у меня есть без этого)
public class EntityASpecifications {
//other specifications
...
public static Specification<EntityA> entityBNameContains(String query) {
return (root, criteriaQuery, criteriaBuilder) -> {
if (query == null) {
return criteriaBuilder.conjunction();
}
criteriaQuery.distinct(true);
return getContainsPredicate(criteriaBuilder, root.join("bEntities").get("name"), query);
};
}
private static Predicate getContainsPredicate(CriteriaBuilder criteriaBuilder, Expression<String> field, String query) {
return (query == null) ? criteriaBuilder.conjunction() : criteriaBuilder.like(criteriaBuilder.lower(field), getContainsPattern(query));
}
private static String getContainsPattern(String searchTerm) {
return (searchTerm.isEmpty()) ? "%" : "%" + searchTerm.toLowerCase() + "%";
}
}
Работает нормально, проблема в том, что когда я пытаюсь использовать сортировку и этот фильтр одновременно
entityARepository.findAll(EntityASpecifications.entityBNameContains("name"), PageRequest.of(page, size, Sort.Direction.ASC, sortColumnName));
Сбой для полей, подключенных к EntityA как EntityB.name (также у меня есть некоторые другие поля с @ManyToOne, которые не работают) со следующим Исключением:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: ORDER BY items must appear in the select list if SELECT DISTINCT is specified
Если я удаляю critQuery.distinct(правда);все будет хорошо, но у меня будут дубликаты, и я не хочу, чтобы они были
Как это исправить и не иметь дублированных результатов одновременно?