我使用以下Specification
来查询与某些Contact
实体绑定的任何ManagedApplication
实体。我传入Collection<Long>
,其中包含我要搜索的ManagedApplication
个实体的ID。
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()
的{{1}}方法,以检索包含符合搜索条件的所有PagingAndSoringRepository
个实体的Page<Contact>
。
这是Contact
。
Repository
以下是我如何调用@Repository
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor<Contact> {
}
方法。
.findAll()
这适用于并返回与传入的ID对应的任何final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
实体绑定的所有Contact
个实体。但是,因为我正在调用ManagedApplication
加入{ {1}}具有.join()
实体的实体,如果一个Contact
在应用ID列表中有多个ManagedApplication
个实体,则该查询将返回重复的Contact
个实体。< / p>
所以我需要知道的是,如何才能使用此ManagedApplication
从查询中返回不同的Contact
个实体?
我知道Contact
有一个Specification
方法可以传递一个布尔值,但是我没有使用我CriteriaQuery
方法中的.distinct()
实例CriteriaQuery
。
以下是我的元模型的相关部分。
Contact_.java:
toPredicate()
ManagedApplication_.java
Specification
答案 0 :(得分:42)
使用query
方法中的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);
...
答案 1 :(得分:4)
可以添加新的静态方法
public static Specification<Object> distinct() {
return (root, query, cb) -> {
query.distinct(true);
return null;
};
}
稍后您可以在创建规范时添加
Specification.where(
YourStaticClassWhereYouCreatedTheUpperMethod.distinct().and(..))