Отличные результаты от спецификации Spring Data JPA, использующей join
у меня есть следующие Specification
что я использую для запроса любого Contact
сущности, которые привязаны к определенным ManagedApplication
объекты. Я прохожу в Collection<Long>
, который содержит идентификаторы ManagedApplication
сущности, которые я ищу.
public static Specification<Contact> findByApp(final Collection<Long> appIds) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
}
}
}
я передаю эту спецификацию .findAll()
метод PagingAndSoringRepository
для получения Page<Contact>
, который будет содержать все Contact
сущности, удовлетворяющие критериям поиска.
здесь Repository
.
@Repository
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor<Contact> {
}
и здесь вот как я называю .findAll()
метод.
final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
это работает и возвращает все Contact
сущности, которые привязаны к любому из ManagedApplication
сущности, соответствующие переданным идентификаторам. Однако, поскольку я звоню .join()
присоединиться к Contact
сущности ManagedApplication
лица, если один Contact
несколько ManagedApplication
сущности в списке идентификаторов приложений, затем запрос вернет дубликат Contact
объекты.
так что я хочу знать, как я могу получить только отдельные Contact
сущности, возвращенные из моего запроса с помощью этого Specification
?
я знаю, что CriteriaQuery
есть .distinct()
метод, которому вы можете передать логическое значение, но я не использую CriteriaQuery
экземпляр toPredicate()
метод Specification
.
вот соответствующие разделы моих метамоделей.
Contact_.java:
@StaticMetamodel(Contact.class)
public class Contact_ {
public static volatile SingularAttribute<Contact, String> firstNm;
public static volatile SingularAttribute<Contact, String> lastNm;
public static volatile SingularAttribute<Contact, String> emailAddress;
public static volatile SetAttribute<Contact, ManagedApplication> managedApplications;
public static volatile SetAttribute<Contact, ContactToStructure> contactToStructures;
}
Managedapplication.java
@StaticMetamodel(ManagedApplication.class)
public class ManagedApplication_ {
public static volatile SingularAttribute<ManagedApplication, Integer> managedApplicationId;
}
1 ответов
использовать в своем toPredicate
метод для вызова метода distinct.
пример:
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
query.distinct(true);
...