【发布时间】:2016-01-06 15:09:54
【问题描述】:
我有以下Specification 用于查询与某些ManagedApplication 实体相关联的任何Contact 实体。我传入一个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);
}
}
}
我将此规范传递给我的PagingAndSoringRepository 的.findAll() 方法以检索一个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);
这有效并返回与传入的 id 对应的任何 ManagedApplication 实体相关联的所有 Contact 实体。但是,由于我调用 .join() 以将 Contact 实体与 @ 987654339@实体,如果一个Contact在app id列表中有多个ManagedApplication实体,那么查询将返回重复的Contact实体。
所以我需要知道的是,我如何才能使用此 Specification 仅从我的查询中返回不同的 Contact 实体?
我知道CriteriaQuery 有一个.distinct() 方法,您可以将布尔值传递给它,但我没有在toPredicate() 的toPredicate() 方法中使用CriteriaQuery 实例@。
这是我的元模型的相关部分。
联系方式_.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;
}
【问题讨论】:
标签: java hibernate jpa spring-data-jpa criteria-api