And*_*ose 19 java hibernate jpa criteria-api spring-data-jpa
我有以下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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我将此规范传递给.findAll()my 的方法,PagingAndSoringRepository以检索Page<Contact>包含Contact符合搜索条件的所有实体的方法.
这是Repository.
@Repository
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor<Contact> {
}
Run Code Online (Sandbox Code Playgroud)
以下是我如何调用该.findAll()方法.
final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
Run Code Online (Sandbox Code Playgroud)
这将工作并返回与传入的id对应的Contact任何实体绑定的所有实体ManagedApplication.但是,由于我要调用实体.join()加入实体,如果app id列表中有多个实体,那么查询将返回重复的实体.ContactManagedApplicationContactManagedApplicationContact
所以我需要知道的是,如何才能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;
}
Run Code Online (Sandbox Code Playgroud)
ManagedApplication_.java
@StaticMetamodel(ManagedApplication.class)
public class ManagedApplication_ {
public static volatile SingularAttribute<ManagedApplication, Integer> managedApplicationId;
}
Run Code Online (Sandbox Code Playgroud)
Ish*_*Ish 47
使用方法中的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);
...
Run Code Online (Sandbox Code Playgroud)
可以添加一个新的静态方法
public static Specification<Object> distinct() {
return (root, query, cb) -> {
query.distinct(true);
return null;
};
}
Run Code Online (Sandbox Code Playgroud)
稍后您可以在创建规范时添加
Specification.where(
YourStaticClassWhereYouCreatedTheUpperMethod.distinct().and(..))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15638 次 |
| 最近记录: |