2016-06-29 42 views
9

List<Hearing>, her biri Date özniteliğine sahip bir sınıfım var Lawsuit.JPA 2 Kriteri API'sında SELECT DISTINCT + ORDER BY SEÇIN

Ben tarihine göre sipariş edilen tüm Lawsuit s seçmeniz gerekir onların Hearing s

Ben ettik Sonuçlara düzleştirmek ayrı kullanmak

CriteriaBuilder   cb = em.getCriteriaBuilder(); 
CriteriaQuery<Lawsuit> cq = cb.createQuery(Lawsuit.class); 
Root<Lawsuit>   root = cq.from(Lawsuit.class); 

gibi CriteriaQuery:

cq.select(root).distinct(true); 

Ben daha sonra katılBen distinct kaçınırsanız

orderList.add(cb.asc(hearing.<Date>get("date"))); 

Her şey gayet iyi çalışıyor, ama bunu kullanırsanız, o şikayetçi değil: Hearing

Join<Lawsuit, Hearing> hearing = root.join("hearings", JoinType.INNER); 

ilePredicate s

predicateList.add(cb.isNotNull(hearing.<Date>get("date"))); 

ve Order ler oluşturmak için SELECT:

'te olmayan alanlara göre sipariş verebilmek

Caused by: org.postgresql.util.PSQLException: ERROR: for SELECT DISTINCT , ORDER BY expressions must appear in select list

List<Hearing> zaten Lawsuit sınıfları erişilebilir döndü, bu yüzden karıştı: nasıl seçim listesine eklemek gerekir?

+0

Well, you-select alt List için ihtiyacım var ve belki sonra tarafından sipariş koyabilirsiniz alt seçimde? Şu anda bakmak için zamanım yok. –

+0

Teşekkür ederim @Nicholas; İç sorguyu kriter api ile nasıl yaparsınız? –

+0

[Bu yanıt] (http://stackoverflow.com/a/35915532/4754790) yardımcı olabilir. –

cevap

5

Sorunun kaynağını başka bir yerde keşfettim ve çözümü, sorulan soruları yapmak için gereksiz hale getirdi; diğer cevaplarda açıklandığı gibi, burada distinct'u gerçekleştirmeniz gerekmemelidir.

yinelenen satırlar

yüklemler kullanılmamış olsa bile koleksiyonları (kök nesnenin niteliklerini) üzerinde gerçekleştirildi hatalı left join s tarafından kökenli edildi:

Join<Lawsuit, Witness> witnesses = root.join("witnesses", JoinType.LEFT); 
if (witnessToFilterWith!=null) { 
    predicateList.add(cb.equal(witnesses.<Long>get("id"),witnessToFilterWith.getId())); 
} 

join açıkçası inner olarak yapılmalıdır ve sadece gerekirse:

if (witnessToFilterWith!=null) { 
    Join<Lawsuit, Witness> witnesses = root.join("witnesses", JoinType.INNER); 
    predicateList.add(cb.equal(witnesses.<Long>get("id"),witnessToFilterWith.getId())); 
} 

Yani, aynı sorun alıyoruz çünkü sen buradayken, , numaralı bağlantıda sorunu araştırın.

0

Ayrıca yinelenmesini olabilir kök tablonun birincil anahtar sütunu dayalı tarafından grup aracılığıyla:

cq.groupBy(root.get("id")); // Assuming that Lawsuite.id is primary key column