特定のSpecification
エンティティに関連付けられているContact
エンティティのクエリに使用する次のManagedApplication
があります。検索するManagedApplication
エンティティのIDを含む_Collection<Long>
_を渡します。
_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()
メソッドに渡して、検索条件を満たすすべてのContact
エンティティを含む_Page<Contact>
_を取得します。
こちらがRepository
です。
_@Repository
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor<Contact> {
}
_
そして、これが.findAll()
メソッドを呼び出す方法です。
_final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
_
これは機能し、渡されたIDに対応するContact
エンティティのいずれかに関連付けられているすべてのManagedApplication
エンティティを返します。ただし、.join()
を呼び出して、 Contact
エンティティとManagedApplication
エンティティ。1つのContact
にアプリIDのリストに複数のManagedApplication
エンティティがある場合、クエリは重複したContact
エンティティ。
ですから、知っておく必要があるのは、このContact
を使用してクエリから返された個別のSpecification
エンティティのみを取得するにはどうすればよいですか?
CriteriaQuery
には.distinct()
メソッドがあり、ブール値を渡すことができることは知っていますが、toPredicate()
でCriteriaQuery
インスタンスを使用していません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;
}
_
query
メソッドでtoPredicate
パラメータを使用して、個別のメソッドを呼び出します。
以下のサンプル:
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);
...