2015-10-08 28 views
6

birleştirmesini kullanır Benbelirli ManagedApplication varlıklarına bağlı olan varlıklar için sorgulamak için kullandığım aşağıdaki Specification var. Ben aradığım ManagedApplication varlıkların kimliklerini içeren bir Collection<Long> geçiriyorum.Spring Data JPA belirtiminden farklı sonuçlar

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

ben arama kriterleri karşılayan tüm Contact varlıkları içerecek bir Page<Contact> almak için benim PagingAndSoringRepository arasında .findAll() yöntemine Bu şartname geçmektedir.

İşte Repository. Ben .findAll() yöntemi çağırıyorum burada nasıl

@Repository 
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor<Contact> {  
} 

Ve olduğunu.

final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable); 

Bu çalışır ve geçirilen kimlikleri karşılık ManagedApplication kişilere herhangi bir ilgisi olan tüm Contact varlıkları döndürür. Ancak, ben bir tane varsa, ManagedApplication kurumla Contact varlık katılmak için .join() arıyorum beri Contact, uygulama kimlikleri listesinde birden çok ManagedApplication varlığına sahip, daha sonra sorgu yinelenen Contact varlıklara dönecektir.

Yani bilmem gereken, bu Specification kullanarak sorgumdan dönen yalnızca farklı Contact varlıkları nasıl alabilirim?

Ben CriteriaQuery size bir boolean değer iletebilirsiniz bir .distinct() yöntemi olduğunu biliyoruz, ama benim Specification arasında toPredicate() yönteminde CriteriaQuery örneği kullanmıyorum.

Metamodellerimin ilgili bölümleri aşağıda verilmiştir.

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

cevap

20

kullanın farklı yöntemi çağırmak için toPredicate yönteminde query parametresi. Aşağıda

Örnek:

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

Evet, işe yarıyor! –

+0

Bu çözüm için teşekkür ederiz, harika çalışıyor! Ayrıca, açıklığa kavuşturmak için, bu farklı ifade gerektiren her yüklemeye 'query.distinct (true)' eklemeniz gerekir. Bu ifadeyi herhangi bir yüklemeye eklemek yeterli değildir ve tüm sorgu için çalışmasını sağlayın .. –

İlgili konular