2015-10-08 105 views
6

我有以下Specification,我用它來查詢與某個ManagedApplication實體綁定的任何Contact實體。我傳入一個Collection<Long>,其中包含我正在搜索的ManagedApplication實體的ID。Spring Data使用連接的JPA規範的不同結果

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); 

這個工作並返回所有Contact實體被綁定到任何ManagedApplication實體對應於通過IDS的。但是,由於我打電話.join()ManagedApplication實體加盟Contact實體,如果一個Contact在應用ID列表中有多個ManagedApplication實體,則查詢將返回重複的Contact實體。

所以我需要知道的是,我怎樣才能得到不同的Contact實體返回從我的查詢使用此Specification

我知道CriteriaQuery.distinct()方法,你可以傳遞一個布爾值,但我不會在我的SpecificationtoPredicate()方法使用CriteriaQuery實例。

以下是我的元模型的相關部分。

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; 
} 

回答

20

使用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); 
    ... 
+0

呀,它的作品! –

+0

謝謝你的解決方案,它的效果很棒! 此外,爲了澄清,你必須添加'query.distinct(true)'到每個需要這個不同語句的謂詞。它不足以將此語句添加到任何謂詞並使其適用於整個查詢。 –

相關問題